Skip to content

MCP server support for CLI#145

Merged
jongalloway merged 2 commits intomainfrom
feature/mcp-server
Mar 31, 2026
Merged

MCP server support for CLI#145
jongalloway merged 2 commits intomainfrom
feature/mcp-server

Conversation

@jongalloway
Copy link
Copy Markdown
Owner

This pull request introduces experimental support for running MarpToPptx as a Model Context Protocol (MCP) server, allowing AI assistants to interact directly with the Markdown-to-PowerPoint pipeline. The changes add the necessary dependencies, command-line flag, server entrypoint, tool implementations, and documentation for this new mode, while keeping the existing CLI workflow unchanged.

MCP Server Integration and Tooling:

  • Adds a new --mcp CLI flag to launch MarpToPptx as an MCP server, allowing AI assistants to interact programmatically with the Markdown-to-PowerPoint pipeline. [1] [2] [3]
  • Implements the MCP server entry point in McpEntry.cs, registering the MarpToPptx toolset and configuring stdio transport.
  • Provides a comprehensive set of MCP tools in MarpToPptxTools.cs for rendering Markdown to PPTX, updating decks, inspecting deck metadata, writing slide IDs, and rendering from a Markdown string.

Project and Dependency Updates:

  • Adds dependencies on Microsoft.Extensions.Hosting and ModelContextProtocol in both the solution and CLI project files to support MCP server functionality. [1] [2]
  • Updates the CLI project description and tags to advertise MCP/AI assistant support.

Documentation:

  • Updates README.md with a new section on the experimental MCP server, including usage instructions, VS Code configuration, and a warning about its experimental status.
  • Adds a detailed doc/mcp-server.md with quick start guides, tool descriptions, iterative workflow, client configuration for VS Code and Claude Desktop, and links to relevant resources.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an experimental MCP (Model Context Protocol) server mode to the MarpToPptx CLI so AI assistants can call into the Markdown→PPTX pipeline over stdio, while preserving the existing CLI behavior.

Changes:

  • Adds --mcp flag to start a stdio-based MCP server instead of running the normal CLI flow.
  • Introduces MCP server host entrypoint plus a MarpToPptx MCP tool surface (render/update/inspect/write slide IDs/render string).
  • Updates packaging/dependencies and documentation to advertise and explain MCP usage.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/MarpToPptx.Cli/Program.cs Adds --mcp dispatch and updates CLI usage text.
src/MarpToPptx.Cli/Mcp/McpEntry.cs New MCP server entrypoint using generic host + stdio transport + tool registration.
src/MarpToPptx.Cli/Mcp/MarpToPptxTools.cs Implements MCP tools wrapping compiler/renderer/update/inspection workflows.
src/MarpToPptx.Cli/MarpToPptx.Cli.csproj Adds MCP/hosting dependencies and updates NuGet metadata.
README.md Documents the new experimental MCP server mode and example client config.
doc/mcp-server.md Adds detailed MCP server documentation and tool list.
Directory.Packages.props Adds centrally-managed versions for new dependencies.
Comments suppressed due to low confidence (1)

src/MarpToPptx.Cli/Mcp/MarpToPptxTools.cs:140

  • The marp_inspect docs claim it returns front-matter directives and presenter notes, but the serialized result currently omits deck.FrontMatter and only returns a hasNotes flag (no notes content). Either include the documented fields or adjust the documentation to match what’s actually returned.
    /// <summary>
    /// Inspect a Marp Markdown file and return structured metadata about the deck
    /// without generating a .pptx file. Returns slide count, per-slide titles,
    /// front-matter directives, theme information, and presenter notes.
    /// Use this to understand or validate a deck before rendering.
    /// </summary>

using MarpToPptx.Pptx.Rendering;

if (args.Contains("--mcp", StringComparer.OrdinalIgnoreCase))
{
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The --mcp early-return runs before any help handling, so marp2pptx --mcp --help (or -h) will start the MCP server instead of printing usage/help. Consider checking for -h/--help before the MCP branch, or handling help explicitly in MCP mode.

Suggested change
{
{
// If help is requested, show standard CLI help instead of starting the MCP server.
if (args.Contains("-h", StringComparer.OrdinalIgnoreCase) || args.Contains("--help", StringComparer.OrdinalIgnoreCase))
{
return await ProgramEntry.RunAsync(args);
}

Copilot uses AI. Check for mistakes.
private static void PrintUsage()
{
Console.WriteLine("marp2pptx <input.md> [-o output.pptx] [--template theme.pptx] [--theme-css theme.css] [--allow-remote-assets] [--write-slide-ids] [--update-existing previous.pptx] [--contrast-warnings off|summary|detailed] [--contrast-report report.txt]");
Console.WriteLine("marp2pptx <input.md> [-o output.pptx] [--template theme.pptx] [--theme-css theme.css] [--allow-remote-assets] [--write-slide-ids] [--update-existing previous.pptx] [--contrast-warnings off|summary|detailed] [--contrast-report report.txt] [--mcp]");
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The usage line implies an input Markdown file is always required, but --mcp is a separate server mode that doesn’t take <input.md>. Consider printing a separate marp2pptx --mcp usage form (or clarifying in the main usage string) to avoid confusing help output.

Suggested change
Console.WriteLine("marp2pptx <input.md> [-o output.pptx] [--template theme.pptx] [--theme-css theme.css] [--allow-remote-assets] [--write-slide-ids] [--update-existing previous.pptx] [--contrast-warnings off|summary|detailed] [--contrast-report report.txt] [--mcp]");
Console.WriteLine("Usage:");
Console.WriteLine(" marp2pptx <input.md> [-o output.pptx] [--template theme.pptx] [--theme-css theme.css] [--allow-remote-assets] [--write-slide-ids] [--update-existing previous.pptx] [--contrast-warnings off|summary|detailed] [--contrast-report report.txt]");
Console.WriteLine(" marp2pptx --mcp");

Copilot uses AI. Check for mistakes.
Comment on lines +78 to +80
catch (Exception ex)
{
return Task.FromResult($"Error: {ex.Message}");
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tools catch all exceptions and return a normal string like Error: ..., which makes failures indistinguishable from successful tool results for MCP clients. Prefer surfacing failures via the MCP error mechanism (e.g., let exceptions propagate or throw a protocol-specific exception) or return a structured payload that includes an explicit success/error field.

Suggested change
catch (Exception ex)
{
return Task.FromResult($"Error: {ex.Message}");
catch (Exception)
{
throw;

Copilot uses AI. Check for mistakes.
Comment on lines +16 to +18
/// Compile Marp-flavored Markdown into an editable PowerPoint (.pptx) file.
/// This is the primary conversion tool. Provide the markdown content or a path to a .md file.
/// Returns the absolute path to the generated .pptx file on success.
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The XML doc for marp_render says it can accept markdown content and that it “Returns the absolute path to the generated .pptx file”, but the method signature only accepts a path and it currently returns a human-readable message string. Please align the docs with actual behavior or change the return value to match the documented contract.

This issue also appears on line 135 of the same file.

Suggested change
/// Compile Marp-flavored Markdown into an editable PowerPoint (.pptx) file.
/// This is the primary conversion tool. Provide the markdown content or a path to a .md file.
/// Returns the absolute path to the generated .pptx file on success.
/// Compile a Marp-flavored Markdown file into an editable PowerPoint (.pptx) file.
/// This is the primary conversion tool. Provide the absolute path to a .md file on disk.
/// Returns a human-readable status message that includes the absolute path to the generated .pptx file on success, or an error message on failure.

Copilot uses AI. Check for mistakes.
Comment on lines +255 to +263
var compiler = new MarpCompiler();
var deck = compiler.Compile(markdown, sourcePath: null, themeCss);

var renderer = new OpenXmlPptxRenderer();
renderer.Render(deck, outputPptxPath, new PptxRenderOptions
{
TemplatePath = templatePath,
});

Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

marp_render_string doesn’t set PptxRenderOptions.SourceDirectory, and the deck’s SourcePath is null, so any relative asset paths in the markdown string will fail to resolve (renderer falls back to a null source directory). Consider adding an optional sourceDirectory/sourcePath parameter and passing it through so relative images/audio/video can be resolved.

Copilot uses AI. Check for mistakes.
Comment on lines +10 to +34
[McpServerToolType]
public sealed class MarpToPptxTools
{
private static readonly JsonSerializerOptions IndentedJson = new() { WriteIndented = true };

/// <summary>
/// Compile Marp-flavored Markdown into an editable PowerPoint (.pptx) file.
/// This is the primary conversion tool. Provide the markdown content or a path to a .md file.
/// Returns the absolute path to the generated .pptx file on success.
/// </summary>
/// <param name="inputMarkdownPath">Absolute path to the input Marp Markdown file.</param>
/// <param name="outputPptxPath">Optional output path for the .pptx file. Defaults to the input file name with a .pptx extension.</param>
/// <param name="themeCssPath">Optional absolute path to a CSS file with Marp-style theme values.</param>
/// <param name="templatePath">Optional absolute path to an existing .pptx template to copy masters/themes from.</param>
/// <param name="allowRemoteAssets">When true, enables HTTP/HTTPS image downloads during rendering. Defaults to false.</param>
/// <param name="writeSlideIds">When true, writes missing slideId directives into the markdown file before rendering. Enables stable identity for future marp_update_deck calls.</param>
[McpServerTool(Title = "Render Markdown to PPTX")]
public Task<string> marp_render(
string inputMarkdownPath,
string? outputPptxPath = null,
string? themeCssPath = null,
string? templatePath = null,
bool allowRemoteAssets = false,
bool writeSlideIds = false)
{
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New MCP server surface (entrypoint + tool methods) is introduced without any automated tests. Since this repo already has CLI-focused tests, consider adding unit tests that call MarpToPptxTools methods against a temp workspace (render, inspect, write-slide-ids, update) to catch regressions and validate tool contracts.

Copilot generated this review using guidance from repository custom instructions.
@jongalloway
Copy link
Copy Markdown
Owner Author

@copilot apply changes based on the comments in this thread

…, exception propagation, sourceDirectory param, and add MCP tool tests

Agent-Logs-Url: https://github.com/jongalloway/MarpToPptx/sessions/7cde92d8-1dd1-41e5-aefc-af9f917b49fc

Co-authored-by: jongalloway <68539+jongalloway@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 31, 2026

@copilot apply changes based on the comments in this thread

Applied all changes from the review thread in commit 11fb3d7:

  • --mcp --help interaction (Program.cs:7): Help flag is now checked before launching the MCP server, so marp2pptx --mcp --help shows CLI usage instead of starting the server.
  • Usage string (Program.cs:199): PrintUsage() now shows two separate forms — marp2pptx <input.md> ... and marp2pptx --mcp.
  • XML doc corrections (MarpToPptxTools.cs:16-18, 255-263): Both marp_render and marp_render_string docs now accurately describe the parameter (file path, not markdown content) and return value (human-readable status message, not the raw path).
  • Exception propagation (MarpToPptxTools.cs:78-80): Removed all catch-all exception handlers across every tool method. Exceptions now propagate to the MCP framework so clients receive proper error responses. The marp_render_string inline validation was also changed from returning "Error: ..." strings to throwing ArgumentException.
  • sourceDirectory for marp_render_string (MarpToPptxTools.cs:255-263): Added an optional sourceDirectory parameter passed through to PptxRenderOptions.SourceDirectory so relative asset paths in markdown strings can be resolved.
  • Unit tests: Added McpToolsTests.cs with 15 tests covering all five tool methods, including success paths and error/exception propagation for each.

@jongalloway jongalloway merged commit c7112b9 into main Mar 31, 2026
5 checks passed
@jongalloway jongalloway deleted the feature/mcp-server branch March 31, 2026 01:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants