Skip to content

Releases: groupdocs-comparison/GroupDocs.Comparison.Mcp

26.7.5

Choose a tag to compare

@github-actions github-actions released this 31 Jul 13:24

26.7.5 — Bump engine to GroupDocs.Comparison 26.7.0 (fixes Linux/macOS render)

What changed

  • Bumped GroupDocsComparison from 26.5.0 to 26.7.0 in build/dependencies.props.
  • Bumped the MCP package version 26.7.4 → 26.7.5, including .mcp/server.json (both version fields), README/llms.txt pins, and the regenerated install/generated/ snippets.

Why

Releases 26.7.1–26.7.4 still shipped engine 26.5.0, whose render path is Windows-only: on Linux/macOS any comparison that renders marked-up output threw DllNotFoundException: gdiplus.dllPlatformNotSupportedException (see 26.7.2's known-limitation note). Engine 26.7.0 moves the render path onto the cross-platform Aspose.Drawing.Common, so compare and analyze_changes now work on Linux/macOS.

Migration / impact

Drop-in replacement for 26.7.4, and the recommended upgrade for Linux/macOS users. No tool-name, input-schema, or response-shape changes. Windows behaviour is unchanged. Linux/macOS gain working compare / analyze_changes for non-overlapping calls.

Full Changelog: 26.7.4...26.7.5

26.7.4

Choose a tag to compare

@github-actions github-actions released this 25 Jul 19:07

26.7.4 — Full configuration surface in install snippets (docs/infra only)

What changed

No server code changes — the bump republishes so the refreshed README (install
buttons above the fold, Codex/Windsurf guides, fixed one-click links) reaches the
NuGet package page, Docker/GHCR, and the MCP Registry.

  • Every install snippet and one-click deeplink (VS Code / Cursor buttons, Claude
    Desktop/Code, VS Code, VS 2022, Cursor, Windsurf, Cline, Rider, Codex) now
    pre-fills all supported environment variables so users see the full
    configuration surface in the install dialog:
    • GROUPDOCS_MCP_STORAGE_PATH — placeholder documents folder
    • GROUPDOCS_MCP_OUTPUT_PATH — same folder as storage by default
    • GROUPDOCS_LICENSE_PATHempty by default (evaluation mode)
  • Verified in GroupDocs.Mcp.Core's LicenseManager: an empty license path is
    handled identically to an unset one (string.IsNullOrEmpty guard → evaluation
    mode with a log warning; a wrong path only logs; SetLicenseFromPath is wrapped
    in try/catch) — an empty value can never fail the server.

Migration / impact

Drop-in — the server binary is identical apart from the version stamp.

Full Changelog: 26.7.3...26.7.4

26.7.3

Choose a tag to compare

@github-actions github-actions released this 24 Jul 18:32

26.7.3 — Discoverability & one-click install uplift (docs/infra only)

What changed

Rollout of the org-wide MCP repo improvement plan (piloted on GroupDocs.Conversion.Mcp
26.7.1). No server code changes — the bump ships the new README to the NuGet package page.

  • README: badge row (NuGet version/downloads, Docker pulls, MCP Registry, Tests-repo CI,
    MIT), demo placeholder, one-click VS Code / Cursor install buttons, pointer to
    ready-made client configs (Claude Code, VS 2022, Cursor, Windsurf, Cline, Rider), and a
    Licensing section documenting the product's evaluation-mode limits with temporary
    license / purchase links.
  • install/config.json + install/generate-install-links.ps1: canonical install config;
    the generator emits install/generated/ (per-client snippets + deeplinks) and rewrites
    the README install-buttons block idempotently. CI drift guard added to
    build_packages.yml (-Check fails the build when generated content is stale).
  • Hygiene: SECURITY.md, CONTRIBUTING.md, issue templates, smithery.yaml,
    docker/README.hub.md, llms.txt licensing section, .vscode/mcp.json published-package
    entry, GitHub topics.

Why

AI-agent users find MCP servers through registries, GitHub topics, and READMEs; installers
copy the first snippet they see. One canonical config keeps every rendered snippet correct
permanently, and licensing up front removes the main evaluation-mode surprise.

Migration / impact

Drop-in — the server binary is identical to 26.7.2 apart from the version stamp.

Full Changelog: 26.7.2...26.7.3

26.7.2

Choose a tag to compare

@github-actions github-actions released this 24 Jul 12:02

26.7.2 — Revert the GDI+ resolver added in 26.7.1 (regression)

What changed

  • Removed GdiPlusResolver and its GdiPlusResolver.Register() call from Program.cs. This reverts the change shipped in 26.7.1.
  • Bumped the MCP package version from 26.7.1 to 26.7.2, including .mcp/server.json (both version fields).

Why

26.7.1 registered a DllImportResolver on System.Drawing.Common to map gdiplus.dll to libgdiplus. That was wrong on two counts and made Linux strictly worse:

  1. Wrong assembly. SetDllImportResolver is per-declaring-assembly. The gdiplus.dll P/Invoke is declared in System.Private.Windows.Core (System.Drawing.Common 9.x's CsWin32 interop layer), not in System.Drawing.Common — so the resolver was never consulted for the failing load.

  2. It broke the type initializer. System.Drawing.Common registers its own resolver inside the System.Drawing.Gdip static constructor. Because 26.7.1 claimed that slot first, Gdip's cctor threw InvalidOperationException: A resolver is already set for the assembly, which escaped the type initializer and disabled System.Drawing entirely:

    TypeInitializationException: Windows.Win32.PInvoke
      → TypeInitializationException: System.Drawing.Gdip
        → InvalidOperationException: A resolver is already set for the assembly
    

Reverting restores the pre-26.7.1 behaviour on Linux (see the known limitation below). Windows was unaffected throughout — the resolver was a no-op there.

Known limitation — compare / analyze_changes on Linux and macOS

Verified by reproducing the failure in a linux/amd64 container against engine 26.5.0:

  • libgdiplus loads fine; the library was never missing. .NET probes only gdiplus.dll(.so) / libgdiplus.dll(.so) and never plain libgdiplus.so.
  • On net10.0 the engine resolves GroupDocs.Comparison.Net100, which depends on System.Drawing.Common 9.0.3. That package is Windows-only since .NET 7 — with the DllImport correctly resolved it simply throws PlatformNotSupportedException: System.Drawing.Common is not supported on non-Windows platforms.
  • Neither adding Aspose.Drawing nor retargeting to net8.0 (GroupDocs.Comparison.Net80 → System.Drawing.Common 8.0.0) avoids it; both fail the same way.

So comparing two different documents — which renders marked-up output — cannot work on non-Windows with engine 26.5.0. Comparing identical documents, and get_document_info, are unaffected. This is an upstream engine limitation, not something the MCP layer can work around; it needs GroupDocs.Comparison to migrate its render path off System.Drawing.Common (as GroupDocs.Metadata already has, via Aspose.Drawing).

The inert System.Drawing.EnableUnixSupport runtime flag is retained only as a marker; it has been a no-op since System.Drawing.Common 7.0.

Migration / impact

Drop-in replacement for 26.7.1, and the recommended upgrade from it. No tool-name, input-schema, or response-shape changes. Windows behaviour is unchanged; Linux/macOS return the original System.Drawing error instead of the resolver-conflict error.

Full Changelog: 26.7.1...26.7.2

26.7.1

Choose a tag to compare

@github-actions github-actions released this 23 Jul 22:03

26.7.1 — Linux/macOS GDI+ resolver (gdiplus.dll DllNotFoundException)

What changed

  • Added GdiPlusResolver and registered it (GdiPlusResolver.Register()) at the top of Program.cs, before any tool can trigger a GDI+ P/Invoke.
  • Bumped the MCP package version from 26.7.0 to 26.7.1 (CalVer), including .mcp/server.json (both version fields).

Why

GroupDocs.Comparison renders its marked-up output through System.Drawing.Common, whose GDI+ interop P/Invokes gdiplus.dll. On Windows that's built in, but on Linux/macOS the system library is libgdiplus.so/.dylib and the .NET native-library loader does not map gdiplus.dll to it — so compare and analyze_changes failed on non-Windows (including inside the Docker image) with DllNotFoundException: Unable to load shared library 'gdiplus.dll', even when libgdiplus was installed. The resolver intercepts that load and points it at the real libgdiplus; it is a no-op on Windows.

Migration / impact

Drop-in replacement for 26.7.0. No tool-name, input-schema, or response-shape changes. Fixes Linux/macOS runs that previously threw the gdiplus.dll error. libgdiplus must still be present (Docker installs it; native users install per the README).

Full Changelog: 26.7.0...26.7.1

26.7.0

Choose a tag to compare

@github-actions github-actions released this 02 Jul 12:21

26.7.0 — Structured changes in Compare + new AnalyzeChanges tool

What changed

  • Compare now returns a structured JSON list of the detected changes alongside the marked-up result file, in a Changes: section appended after the saved-file line. Each change carries id, type, componentType, changedText (the specific inserted/deleted fragment), surrounding sourceText/targetText, tabular row/column/columnHeader, and styleChanges (per-property old/new values). Empty fields are omitted to keep the payload compact.
  • New AnalyzeChanges tool returns the same structured change list without rendering or saving a result file. It calls the engine's parameterless Compare(), so it pays only for the diff — no document is written to storage. Use it when the user wants to summarize, explain, or reason about what changed rather than obtain the rendered diff file.
  • Both tools' [Description] text guides the agent's routing: Compare for "save the marked-up file", AnalyzeChanges for "what changed?" analysis.
  • Bumped the GroupDocs.Comparison engine dependency to 26.5.0, which exposes the Cells Row / Column / ColumnHeader fields used by the change projection.

Why

The previous Compare response exposed only a change count and the saved file path. The file is for a human to open; the calling LLM cannot read it. All the semantic detail the engine already computes in GetChanges() (what changed, of what kind, where) was discarded. Surfacing it as structured JSON lets the agent actually answer "what changed?" without a human opening the document. AnalyzeChanges splits out the analysis-only intent so agents can skip the cost of rendering a file when the user only wants the diff explained.

Migration / impact

Additive and backward-compatible. Compare's existing output (summary line + saved-file line) is unchanged; the Changes: JSON block is appended after it, so consumers pattern-matching on the leading summary/path text are unaffected. AnalyzeChanges is a new tool — no impact on existing Compare / GetDocumentInfo callers.

Full Changelog: 26.5.2...26.7.0

26.5.2

Choose a tag to compare

@github-actions github-actions released this 17 May 22:29

26.5.2 — Engine exceptions surfaced in tool responses instead of a generic MCP wrapper

What changed

  • Compare and GetDocumentInfo now wrap the GroupDocs.Comparison engine call in a try/catch. On failure the tool response carries the underlying exception — type, message, and up to 5 levels of inner-exception chain — instead of ModelContextProtocol's generic An error occurred invoking '<tool>'. wrapper.
  • Compare failures begin with Compare failed for '<source>' vs '<target>': ; GetDocumentInfo failures begin with Document-info lookup failed for '<file>': .
  • GetDocumentInfo no longer takes the OutputHelper dependency. It was injected but unused — the tool returns raw JSON directly (see 26.5.1). This is an internal signature change only; OutputHelper was never part of the MCP tool input schema, so there is no wire-name or client-visible change.
  • Both tools' [Description] text now documents the failure-prefix behaviour so agents can recognise and relay engine errors.

Why

ModelContextProtocol's default exception handling collapses every engine failure to An error occurred invoking 'compare'. — which hides the real cause (missing Linux native fonts, an unsupported format, a corrupt stream, …) and makes failures indistinguishable in CI logs and at the client. Surfacing the underlying exception type + message + inner chain makes failures diagnosable from the tool response alone. Pattern per Pitfall #18 of the clone prompt.

Migration / impact

Drop-in replacement for 26.5.1. No public-API, tool-name, or input-schema changes. Successful calls return exactly as before. Failing calls now return a descriptive error string (still a normal tool response, not an MCP protocol error) — any consumer pattern-matching on the old An error occurred invoking … text should switch to the new Compare failed for … / Document-info lookup failed for … prefixes.

Full Changelog: 26.5.1...26.5.2

26.5.1

Choose a tag to compare

@github-actions github-actions released this 03 May 23:47

26.5.1 — GetDocumentInfo JSON response no longer truncated mid-document

What changed

  • GetDocumentInfoTool now returns raw JSON directly instead of routing it through OutputHelper.TruncateText.
  • OutputHelper.TruncateText is intended for plain-text output: when the input exceeds McpConfig.MaxOutputCharacters (default 5000), it appends a [Output truncated — showing first X of Y characters. ...] marker on a new line. That marker is non-JSON and breaks any consumer using JsonDocument.Parse / JsonSerializer.Deserialize on the response.
  • Affected callers in practice: documents with many pages (per-page width/height list pushes JSON past 5 KB), plus any client that strict-parses the tool response. Lenient consumers (Claude, Cursor, VS Code Copilot) tolerate the trailing marker, so user-visible AI-agent flows in 26.5.0 are unaffected.

Why

Tools that emit structured JSON should always return valid JSON regardless of size. Truncation should be expressed inside the JSON document (e.g. capped inner array + truncated: true flag) rather than by appending a non-JSON marker line. In practice the response is bounded by API realities (a few KB to ~30 KB), so removing the wrapping is sufficient — no in-document truncation needed today.

Migration / impact

Drop-in replacement for 26.5.0. No public-API or wire-name changes. Tool responses now contain only the JSON document; previous trailing marker line for ~5KB+ responses is gone. Strict-JSON parsers that broke against 26.5.0 work cleanly against 26.5.1.

Full Changelog: 26.5.0...26.5.1

26.5.0

Choose a tag to compare

@github-actions github-actions released this 03 May 22:06

Initial public release of GroupDocs.Comparison MCP Server

What changed

  • NuGet package GroupDocs.Comparison.Mcp published with McpServer package type.
  • Two MCP tools exposed:
    • Compare — compare two documents (source vs target), produce a marked-up result file with the differences highlighted, and return a change-count summary. Supports PDF, Word, Excel, PowerPoint, ODT, RTF, TXT, HTML, and 30+ more formats; takes optional sourcePassword / targetPassword for protected documents.
    • GetDocumentInfo — inspect a single source document and return file type, page count, file size, and per-page dimensions as JSON. No comparison performed. Optional password for protected documents.
  • Installable via dnx GroupDocs.Comparison.Mcp@26.5.0 --yes (.NET 10 SDK required) or dotnet tool install -g.
  • Docker image published to ghcr.io/groupdocs-comparison/comparison-net-mcp and docker.io/groupdocs/comparison-net-mcp.
  • Environment variables: GROUPDOCS_MCP_STORAGE_PATH, optional GROUPDOCS_MCP_OUTPUT_PATH, GROUPDOCS_LICENSE_PATH.
  • Linux native graphics deps wired up: SkiaSharp.NativeAssets.Linux.NoDependencies (3.119.0) is referenced because GroupDocs.Comparison's nuspec already declares the SkiaSharp managed and native packages — we pin explicitly so transitive resolution stays deterministic. libgdiplus + libfontconfig1 are installed in the Docker image and the System.Drawing.EnableUnixSupport runtime flag is set because Comparison's Cells (Excel) and image-format paths still call System.Drawing.Common.

Why

Third product MCP server in the GroupDocs MCP framework (after Metadata and Conversion). Exposes
GroupDocs.Comparison for .NET as an AI-callable tool for Claude, Cursor,
VS Code / GitHub Copilot, and other MCP-compatible agents.

Migration / impact

First release — no migration required.

Full Changelog: https://github.com/groupdocs-comparison/GroupDocs.Comparison.Mcp/commits/26.5.0