Releases: groupdocs-comparison/GroupDocs.Comparison.Mcp
Release list
26.7.5
26.7.5 — Bump engine to GroupDocs.Comparison 26.7.0 (fixes Linux/macOS render)
What changed
- Bumped
GroupDocsComparisonfrom 26.5.0 to 26.7.0 inbuild/dependencies.props. - Bumped the MCP package version 26.7.4 → 26.7.5, including
.mcp/server.json(bothversionfields), README/llms.txt pins, and the regeneratedinstall/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.dll → PlatformNotSupportedException (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
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 folderGROUPDOCS_MCP_OUTPUT_PATH— same folder as storage by defaultGROUPDOCS_LICENSE_PATH— empty by default (evaluation mode)
- Verified in
GroupDocs.Mcp.Core'sLicenseManager: an empty license path is
handled identically to an unset one (string.IsNullOrEmptyguard → evaluation
mode with a log warning; a wrong path only logs;SetLicenseFromPathis 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
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 emitsinstall/generated/(per-client snippets + deeplinks) and rewrites
the README install-buttons block idempotently. CI drift guard added to
build_packages.yml(-Checkfails 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.jsonpublished-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
26.7.2 — Revert the GDI+ resolver added in 26.7.1 (regression)
What changed
- Removed
GdiPlusResolverand itsGdiPlusResolver.Register()call fromProgram.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(bothversionfields).
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:
-
Wrong assembly.
SetDllImportResolveris per-declaring-assembly. Thegdiplus.dllP/Invoke is declared inSystem.Private.Windows.Core(System.Drawing.Common 9.x's CsWin32 interop layer), not inSystem.Drawing.Common— so the resolver was never consulted for the failing load. -
It broke the type initializer.
System.Drawing.Commonregisters its own resolver inside theSystem.Drawing.Gdipstatic constructor. Because 26.7.1 claimed that slot first, Gdip's cctor threwInvalidOperationException: 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:
libgdiplusloads fine; the library was never missing. .NET probes onlygdiplus.dll(.so)/libgdiplus.dll(.so)and never plainlibgdiplus.so.- On
net10.0the engine resolvesGroupDocs.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 throwsPlatformNotSupportedException: System.Drawing.Common is not supported on non-Windows platforms. - Neither adding
Aspose.Drawingnor retargeting tonet8.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
26.7.1 — Linux/macOS GDI+ resolver (gdiplus.dll DllNotFoundException)
What changed
- Added
GdiPlusResolverand registered it (GdiPlusResolver.Register()) at the top ofProgram.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(bothversionfields).
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
26.7.0 — Structured changes in Compare + new AnalyzeChanges tool
What changed
Comparenow returns a structured JSON list of the detected changes alongside the marked-up result file, in aChanges:section appended after the saved-file line. Each change carriesid,type,componentType,changedText(the specific inserted/deleted fragment), surroundingsourceText/targetText, tabularrow/column/columnHeader, andstyleChanges(per-property old/new values). Empty fields are omitted to keep the payload compact.- New
AnalyzeChangestool returns the same structured change list without rendering or saving a result file. It calls the engine's parameterlessCompare(), 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:Comparefor "save the marked-up file",AnalyzeChangesfor "what changed?" analysis. - Bumped the
GroupDocs.Comparisonengine dependency to26.5.0, which exposes the CellsRow/Column/ColumnHeaderfields 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
26.5.2 — Engine exceptions surfaced in tool responses instead of a generic MCP wrapper
What changed
CompareandGetDocumentInfonow wrap the GroupDocs.Comparison engine call in atry/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 genericAn error occurred invoking '<tool>'.wrapper.Comparefailures begin withCompare failed for '<source>' vs '<target>':;GetDocumentInfofailures begin withDocument-info lookup failed for '<file>':.GetDocumentInfono longer takes theOutputHelperdependency. It was injected but unused — the tool returns raw JSON directly (see 26.5.1). This is an internal signature change only;OutputHelperwas 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
26.5.1 — GetDocumentInfo JSON response no longer truncated mid-document
What changed
GetDocumentInfoToolnow returns raw JSON directly instead of routing it throughOutputHelper.TruncateText.OutputHelper.TruncateTextis intended for plain-text output: when the input exceedsMcpConfig.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 usingJsonDocument.Parse/JsonSerializer.Deserializeon 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
Initial public release of GroupDocs.Comparison MCP Server
What changed
- NuGet package
GroupDocs.Comparison.Mcppublished withMcpServerpackage 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 optionalsourcePassword/targetPasswordfor 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. Optionalpasswordfor protected documents.
- Installable via
dnx GroupDocs.Comparison.Mcp@26.5.0 --yes(.NET 10 SDK required) ordotnet tool install -g. - Docker image published to
ghcr.io/groupdocs-comparison/comparison-net-mcpanddocker.io/groupdocs/comparison-net-mcp. - Environment variables:
GROUPDOCS_MCP_STORAGE_PATH, optionalGROUPDOCS_MCP_OUTPUT_PATH,GROUPDOCS_LICENSE_PATH. - Linux native graphics deps wired up:
SkiaSharp.NativeAssets.Linux.NoDependencies(3.119.0) is referenced becauseGroupDocs.Comparison's nuspec already declares the SkiaSharp managed and native packages — we pin explicitly so transitive resolution stays deterministic.libgdiplus+libfontconfig1are installed in the Docker image and theSystem.Drawing.EnableUnixSupportruntime flag is set because Comparison's Cells (Excel) and image-format paths still callSystem.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