structdiff
Provides semantic diffing and inspection for .env files, comparing values as strings and warning about duplicate keys or parsing traps.
Provides semantic diffing and inspection for TOML configuration files, reporting changes by path while ignoring key order and formatting, including type changes and array moves.
Provides semantic diffing and inspection for YAML files, resolving anchors, aliases, and merge keys, comparing multi-document YAML as document lists, and warning about duplicate keys or multi-document traps.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@structdiffWhat changed between deploy/prod.yaml and deploy/staging.yaml, ignoring replica counts?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
structdiff-mcp
An MCP server that tells an AI agent what actually changed between two JSON / YAML / TOML / CSV / .env / INI files, by path, ignoring key order and formatting. A line diff of two configs shows 400 changed lines because someone re-sorted the keys; this shows the one port that changed.
Why this one, when other diff MCP servers exist? Servers such as confdiff-mcp, diff-mcp and
mcp-config-tools (Node/npm) already diff configs. This one is Python (uvx structdiff-mcp, no Node)
and goes further on the cases that make diffs lie:
Lists are matched by identity, not position.
users[id=3]moved to the front is onemovedentry, not a cascade of edits. Match byid/name/key(or your own field), by index, or as a set.A JSON Patch you can trust.
as_json_patchreturns an RFC 6902 patch that is verified by applying it before it is returned, and the test suite applies generated patches to thousands of random documents with two independent appliers (ours andjsonpatch).Honest about types.
1vs"1"is atype_changed,nullvs a missing key is an add/remove, big integers stay exact,NaNequalsNaN,0.1+0.2vs0.3is equal with a tolerance.Warns about traps instead of silently picking one: duplicate JSON/YAML/.env keys, multi-document YAML, comments in JSON, mixed CSV delimiters or encodings.
Keyed CSV diffing that streams the second file: added/removed/changed rows, per-cell changes, column additions, duplicate keys.
Read-only and sandboxed to the folders you allow; YAML is parsed with the safe loader only.
Install
Claude Code:
claude mcp add structdiff -- uvx structdiff-mcp --dir "C:\path\to\your\projects"Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"structdiff": {
"command": "uvx",
"args": ["structdiff-mcp", "--dir", "C:\\path\\to\\your\\projects"]
}
}
}--dir may be repeated. Without it the server can read only the folder it was started in.
Relative file paths resolve against the first --dir.
Related MCP server: GroupDocs.Comparison MCP Server
Tools
Tool | What it does |
| Semantic diff of two files (format auto-detected; a and b may differ in format) |
| The same for two pasted strings (format required) |
| Row-level CSV/TSV diff using |
| RFC 6902 patch turning a into b, verified before it is returned |
| Show what a JSON Patch does to a document (nothing is written) |
| How a file parses: format, encoding, shape, and warnings (duplicate keys, multi-doc, ...) |
Example result of diff_text on two JSON documents (abs_tol=1e-9):
{
"identical": false,
"summary": {"added": 0, "removed": 0, "changed": 1, "type_changed": 1, "moved": 1, "total": 3},
"changes": [
{"op": "type_changed", "path": "$.port", "old": 8080, "new": "8080", "old_type": "number", "new_type": "string"},
{"op": "changed", "path": "$.users[id=1].role", "old": "admin", "new": "owner"},
{"op": "moved", "path": "$.users[id=3]", "from_index": 2, "to_index": 0}
]
}Options shared by the diff tools
array_match:auto(default: key field if one is present and unique in every item, else position),index,key(like auto, but warns when no key works),set(order-insensitive, duplicate-aware).array_keys: candidate key fields, default["id", "name", "key"].ignore: paths to skip, e.g.["$.metadata.updatedAt", "$.items[*].etag", "*.timestamp"].*matches any text including dots and brackets; patterns must start with$or*.abs_tol,rel_tol: numeric tolerance.1and1.0are always equal.strip_comments: allow//,/* */and trailing commas in JSON (automatic for.jsonc).encoding:autohonours UTF-8/16/32 BOMs, otherwise UTF-8; passcp1252etc. explicitly for legacy files.max_changes,max_value_chars: caps on output. Summary counts are always complete.
Paths look like $.servers[id=3].port, $['odd.key'], $.tags[*] (set mode) or $[2] (by index).
Try asking
"Diff
deploy/prod.yamlanddeploy/staging.yamland ignore the replica counts.""What changed between
package.jsonon main and this one I pasted? Only the dependencies matter.""Compare
config.old.tomlandconfig.new.toml; treat floats within 1e-6 as equal.""Compare these two exports on
customer_idand tell me which cells changed, and which columns are new.""Give me a JSON Patch that turns
a.jsonintob.json, and show me what applying it toc.jsonwould do.""Does
settings.jsonhave duplicate keys or comments that would confuse a parser?"
Limits and behaviour worth knowing
YAML documents are compared after loading: anchors, aliases and merge keys are resolved, dates become ISO strings, comments are ignored. Multi-document YAML is compared as a list of documents.
A key
1and a keytruein one YAML mapping collide in Python; that is reported as a duplicate-key warning.INI values are strings and
[DEFAULT]is treated as an ordinary section..envvalues are strings.NaN and Infinity cannot appear in a JSON Patch (
as_json_patchrefuses); in diff output they are shown as strings.as_json_patchwithignoreor tolerance options produces a patch whose result equals b only up to those options. A list containing ignored items is left unpatched, with a warning.Structured files are limited to 50 MB;
csv_diffindexes file a in memory (limit 2 million rows) and streams file b.
Security
Read-only. No tool writes, moves or deletes anything.
Sandboxed. Files must resolve (symlinks followed) inside a
--dirfolder; anything else is refused. Only pass folders you are happy for the agent to read.Safe YAML. Only PyYAML's
SafeLoaderis used;!!python/...tags are rejected. Recursive aliases and alias bombs are detected and refused (5 million value budget, 100 levels of nesting).Pasted text is limited to 10 MB. File contents are returned in diff output (truncated per value), so do not point the server at secrets you do not want in the conversation; use
ignorefor sensitive paths.
Develop
uv sync --extra test
uv run pytest # includes ~6000 property-test cases and a real stdio session
uv run ruff check src tests
uv run mypy --strict srcMIT licensed. A from-scratch tutorial that builds a minimal version of this server is in structdiff-mcp-the-hard-way.
Available Tools
6 toolsapply_previewA
Preview what an RFC 6902 JSON Patch does to a document, without writing anything.
Supports add, remove, replace, move, copy and test. Returns the patched document and a semantic summary of what changed versus the original. A failing operation is reported with its index and reason, and nothing is returned in that case.
Args: a: file path, or the document itself when inputs='text'. patch: the patch as a JSON array (or a JSON string of one). inputs, format, strip_comments, encoding: as in diff_files. max_result_chars: the result is cut off after this many characters (the summary is not).
| Name | Required | Description | Default |
|---|---|---|---|
| a | Yes | ||
| patch | Yes | ||
| format | No | auto | |
| inputs | No | files | |
| encoding | No | auto | |
| strip_comments | No | ||
| max_result_chars | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does substantial work: it declares the side-effect-free nature, enumerates the supported operations, describes the return payload (patched document plus semantic summary), and specifies failure semantics (failing operation reported with index and reason, no result returned). It stops short of stating what happens on unreadable files or malformed non-patch input.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The behavioural summary is front-loaded and free of filler, and the Args block is easy to scan. The only weakness is that several arguments are covered by a single cross-reference rather than stated directly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter, non-destructive tool with an output schema, the description covers what it does, what it returns, how truncation interacts with the result, and how failures surface. The return-value details are appropriately brief because an output schema exists.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must supply the meaning. It does well for 'a', 'patch', and 'max_result_chars' (including the useful detail that the summary is not truncated), but 'format', 'inputs', 'strip_comments' and 'encoding' are deferred wholesale to 'as in diff_files', leaving the agent to consult another definition.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence names a specific verb (preview), a specific resource (an RFC 6902 JSON Patch applied to a document) and a scope qualifier ('without writing anything'). It also clearly separates the tool from the sibling as_json_patch, which produces patches rather than consuming them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by 'preview ... without writing anything' and by the note that 'inputs, format, strip_comments, encoding' behave 'as in diff_files', which points the agent at a sibling for shared semantics. However, it never explicitly states when to prefer this over another tool, nor does it name as_json_patch as the way to generate the patch this tool consumes.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
as_json_patchA
Generate an RFC 6902 JSON Patch that transforms document a into document b.
The patch is verified before it is returned: it is applied to a and the result is re-diffed against b (using the same options), so a patch that does not reproduce b is never returned. Lists are patched with remove/add/move so keyed items keep their identity. With ignore or tolerance options the patched a equals b only up to those options. NaN/Infinity cannot be expressed in JSON and are rejected.
Args: a, b: file paths, or the documents themselves when inputs='text'. inputs: 'files' (default) or 'text'; text requires an explicit format. format, array_match, array_keys, ignore, abs_tol, rel_tol, strip_comments, encoding: as in diff_files.
| Name | Required | Description | Default |
|---|---|---|---|
| a | Yes | ||
| b | Yes | ||
| format | No | auto | |
| ignore | No | ||
| inputs | No | files | |
| abs_tol | No | ||
| rel_tol | No | ||
| encoding | No | auto | |
| array_keys | No | ||
| array_match | No | auto | |
| strip_comments | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations supplied, the description carries real weight and does so well: it discloses that every patch is self-verified by applying it to a and re-diffing against b, that arrays use remove/add/move to preserve keyed item identity, that output is only equivalent up to ignore/tolerance options, and that NaN/Infinity are rejected. Remaining gaps are smaller — no mention of size limits, performance, or side effects (whether anything is written to disk) — which keeps it from a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The structure is front-loaded and logical: purpose first, then verification and array/edge-case semantics, then a compact args block. Nearly every sentence adds information, though the deferred 'as in diff_files' line is a low-value substitute for actual parameter meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-format explanation is appropriately omitted, and the safety story is clear since the tool generates rather than applies a patch. However, for an 11-parameter tool with zero schema descriptions, leaving eight parameters to be looked up elsewhere means the definition is not fully self-contained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 11 parameters, so the description must compensate, and it only partly does. It clarifies a/b as file paths versus inline documents depending on inputs, and states that text mode requires an explicit format, but the remaining eight parameters (format, array_match, array_keys, ignore, abs_tol, rel_tol, strip_comments, encoding) are disposed of with 'as in diff_files' — a cross-reference that helps only if the agent has that sibling's documentation loaded.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence names a specific verb and artifact: 'Generate an RFC 6902 JSON Patch that transforms document a into document b.' That is far more precise than a generic diff tool, but the description never explicitly contrasts itself with the listed siblings (diff_files, diff_text, apply_preview), leaving the agent to infer that this one emits a patch rather than a human-readable diff.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: 'inputs: files (default) or text; text requires an explicit format' tells the agent which mode to pick, and the ignore/tolerance caveat hints at when the result is approximate. There is no explicit statement of when to call as_json_patch instead of diff_files or apply_preview, and no stated prerequisites or failure conditions beyond NaN/Infinity rejection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
csv_diffA
Row-level diff of two CSV/TSV files: added, removed and changed rows, per-cell changes, columns.
Rows are paired by key_columns (e.g. ["id"] or ["country", "year"]); without key_columns whole rows are compared as an unordered set, so an edited row appears as one removed plus one added row. Reports added/removed columns separately (cells of those columns are not compared) and whether the common columns were reordered. Duplicate keys are paired in file order and reported as a warning. The delimiter (, ; tab |) and BOM/UTF-16 encodings are detected automatically. File a is indexed in memory (limit 2 million rows); file b is streamed.
Args: a, b: file paths. key_columns: column names identifying a row; they must exist in both files. ignore_columns: column names or globs (e.g. "updated_*") whose cells are not compared. delimiter: a single character; auto-detected when omitted. abs_tol, rel_tol: numeric cells (both sides parse as numbers) within tolerance are equal; requires key_columns. max_changes: cap on entries in each of added_rows, removed_rows and changed_rows; summary counts are always complete.
| Name | Required | Description | Default |
|---|---|---|---|
| a | Yes | ||
| b | Yes | ||
| abs_tol | No | ||
| rel_tol | No | ||
| encoding | No | auto | |
| delimiter | No | ||
| key_columns | No | ||
| max_changes | No | ||
| ignore_columns | No | ||
| max_value_chars | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does so unusually well: it discloses that file a is indexed in memory (2 million row limit) while b is streamed, that duplicate keys are paired in file order and surfaced as a warning, that added/removed column cells are skipped, and that max_changes caps list entries while summary counts stay complete. Encoding/delimiter auto-detection is also stated, which is exactly the kind of operational context annotations would otherwise supply.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the outcome, then a paragraph of semantics, then a compact Args block — a good structure for a ten-parameter tool. A couple of clauses (BOM/UTF-16 parenthetical, delimiter character list) are incidental but still operational, so waste is minimal.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values are correctly left out, and the description covers everything else an agent needs to call it safely except the encoding and max_value_chars parameters. For a ten-parameter comparison tool with zero annotation and zero schema-description support, that is near complete but not fully closed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% and the schema titles are bare ('A', 'Abs Tol', 'Max Value Chars'), so the Args block does most of the work: it defines a/b as file paths, explains key_columns constraints, ignore_columns glob syntax with an example, and crucially that abs_tol/rel_tol apply only to numeric cells and require key_columns. Two of ten parameters, encoding and max_value_chars, are never explained anywhere, so an agent must guess what max_value_chars truncates.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a precise verb+resource+output enumeration: 'Row-level diff of two CSV/TSV files: added, removed and changed rows, per-cell changes, columns.' The CSV/TSV scope plus the row-level framing cleanly separates it from siblings diff_files and diff_text, so an agent can select it without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives strong conditional guidance inside the tool: key_columns pairs rows by identity, without it rows are compared as an unordered set so an edit becomes a remove+add, and tolerances 'requires key_columns'. It never explicitly states when to use this instead of diff_files or diff_text, leaving sibling routing to inference from the names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
diff_filesA
Semantic diff of two files: what changed, by path, ignoring key order and formatting.
Reads JSON, JSONC, YAML (safe subset, multi-document supported), TOML, .env and INI files (format is detected from the file name; a and b may be different formats). Returns {identical, summary{added, removed, changed, type_changed, moved, total}, changes[], warnings[]}. Each change has an op ('added', 'removed', 'changed', 'type_changed', 'moved'), a JSONPath-like path such as $.servers[id=3].port, and old/new values (truncated to max_value_chars). A value going from 1 to "1" is type_changed; null versus a missing key is reported as a key that was added or removed, never as a change.
Args: a, b: file paths (relative paths resolve against the first --dir). format: json, jsonc, yaml, toml, env, ini, csv, or auto (from the extension). array_match: how list items are paired. 'auto' (default) matches lists of objects by the first of array_keys that is present and unique in every item, and falls back to position; 'index' pairs by position; 'key' is like auto but warns when no key works; 'set' ignores order and duplicates-aware compares items by value (good for tag lists). Items matched by key that changed position are reported as 'moved'. array_keys: candidate key fields, default ["id", "name", "key"]. ignore: patterns of paths to skip. '' matches any text, including dots and brackets: '$.metadata.updatedAt', '$.items[].etag', '.timestamp'. Must start with '$' or ''. abs_tol, rel_tol: numbers within these tolerances are treated as equal (0.1+0.2 vs 0.3 needs abs_tol=1e-9). 1 and 1.0 are always equal; big integers stay exact. strip_comments: remove // and /* */ comments and trailing commas before parsing JSON (always on for .jsonc). encoding: 'auto' honours UTF-8/16/32 BOMs, otherwise UTF-8; or give e.g. 'cp1252'. max_changes: cap on listed changes; summary counts are always complete.
| Name | Required | Description | Default |
|---|---|---|---|
| a | Yes | ||
| b | Yes | ||
| format | No | auto | |
| ignore | No | ||
| abs_tol | No | ||
| rel_tol | No | ||
| encoding | No | auto | |
| array_keys | No | ||
| array_match | No | auto | |
| max_changes | No | ||
| strip_comments | No | ||
| max_value_chars | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations supplied, the description carries the burden and does well: it discloses format detection, safe YAML parsing, output structure, change operation types, null-versus-missing-key semantics, tolerance behavior, truncation, and that summary counts remain complete under max_changes. It does not explicitly state that the tool is read-only or describe error behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with purpose and return shape, then uses a structured Args list, which suits a complex 12-parameter tool. It is dense but mostly earns its space, though some return-shape detail is redundant because an output schema exists.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex file-diffing tool with 12 parameters and an existing output schema, the description is nearly complete: parameters and core behavior are well covered. Minor gaps remain around explicit read-only/non-destructive status, error handling, and the reference to a '--dir' option that may not map cleanly to an MCP context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it explains all 12 parameters meaningfully. It documents path resolution, format options, array matching modes, key candidates, ignore-pattern syntax and constraints, tolerance semantics with examples, encoding behavior, comment stripping, and the caps on changes and value length.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: semantic diff of two files, with supported structured formats and a clear focus on semantic rather than textual comparison. It does not explicitly distinguish itself from sibling tools such as diff_text or csv_diff, and the prose format list omits CSV though the format argument includes it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by 'semantic diff' and the supported structured formats, and the array_match options include guidance on when each matching mode is appropriate. However, there is no explicit when-to-use guidance versus sibling tools like diff_text, csv_diff, or inspect_file, nor are there stated exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
diff_textA
Semantic diff of two pasted strings (same output and options as diff_files).
Use this for content that is not on disk. 'format' is required because it cannot be guessed from a name. Both strings must be in the same format. See diff_files for the output shape and for array_match, array_keys, ignore, abs_tol, rel_tol and strip_comments. For CSV text each row becomes an object, so array_keys can match rows by id; use csv_diff on files for large CSVs.
| Name | Required | Description | Default |
|---|---|---|---|
| a | Yes | ||
| b | Yes | ||
| format | Yes | ||
| ignore | No | ||
| abs_tol | No | ||
| rel_tol | No | ||
| array_keys | No | ||
| array_match | No | auto | |
| max_changes | No | ||
| strip_comments | No | ||
| max_value_chars | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does disclose non-obvious behavior: format is mandatory because it can't be inferred, both inputs must share one format, and CSV rows are parsed into objects. It also points to diff_files for output shape, which is acceptable since an output schema exists. It omits explicit safety/read-only framing, but a diff tool's non-mutating nature is self-evident.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and the key constraint (format is required) are front-loaded, and the sentences stay short. A bit of space is spent on cross-references to diff_files, but each sentence carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 11-parameter tool with zero schema descriptions, the definition covers the essentials (inputs, format requirement, CSV behavior) and the output schema handles return values. However, meaningful parameter semantics are delegated to diff_files, forcing an extra lookup before the agent can use options like abs_tol or array_match confidently.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% across 11 parameters, so the description must compensate; it names ignore, abs_tol, rel_tol, array_keys, array_match and strip_comments, but only by name, deferring their meaning to diff_files. max_changes and max_value_chars are never mentioned, and no format or unit details (e.g. tolerance semantics) are given locally.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a concrete verb and resource ('Semantic diff of two pasted strings') and immediately differentiates from diff_files by noting the inputs are pasted rather than on disk. An agent can distinguish it from diff_files and csv_diff without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit selection rule ('Use this for content that is not on disk') and names the alternative for the file case. It also routes large CSV files to csv_diff. It stops short of stating when-not conditions for small/on-disk files, so it is clear context rather than full routing logic.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
inspect_fileA
Check how a file parses before diffing it: format, encoding, top-level shape, warnings.
Surfaces things that make diffs surprising: duplicate keys (JSON, YAML, .env), multi-document YAML, comments in JSON, an unexpected delimiter or encoding in CSV. For CSV it reports the columns, the detected delimiter and the row count (streamed, so large files are fine).
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| format | No | auto | |
| encoding | No | auto | |
| strip_comments | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does well: it discloses that the tool detects duplicate keys across JSON/YAML/.env, multi-document YAML, comments in JSON, and delimiter/encoding anomalies, and that CSV inspection reports columns, delimiter and row count. It also notes streaming behavior so large files are handled. It does not state side effects, error behavior, or that the operation is strictly read-only, which keeps it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose sentence is front-loaded and the supporting detail is organized by concern (surprising diffs, then CSV specifics). The middle catalogue of anomalies is dense but each item earns its place; only minor tightening is possible.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need little explanation, and the description is adequate for a read-only inspection tool. However, with four undocumented parameters, the unmentioned 'strip_comments' flag and the 'auto' format/encoding defaults leave real behavioral gaps an agent must guess at.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and four parameters exist, so the description must compensate. 'Format' and 'encoding' appear only as reported outputs rather than as inputs, and 'strip_comments' is not addressed at all, nor is the 'auto' default explained. Meaning is left largely to inference from the enum.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Check how a file parses") and enumerates exactly what it reports: format, encoding, top-level shape, warnings. It also positions itself against the diffing siblings by saying it is done "before diffing it", so an agent can distinguish it from diff_files/csv_diff without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear usage context: run it before a diff to understand why diffs look surprising. The condition that selects this tool (pre-diff verification) is explicit, though there are no exclusions or guidance on when to skip inspection and go straight to diff_files.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v0.1.0- First observed
apply_preview - First observed
as_json_patch - First observed
csv_diff - First observed
diff_files - First observed
diff_text - First observed
inspect_file
TDQS
Scored across 6 tools
Most tools occupy distinct niches: inspect_file (parse check), diff_files/diff_text (same engine, different input source), csv_diff (row-level/keyed CSV), and the as_json_patch/apply_preview pair (inverse operations). The only real overlap is csv_diff versus diff_files with format=csv, but the descriptions explicitly route large CSVs to csv_diff and pasted content to diff_text, so an agent can choose correctly. Minor residual risk that an agent picks diff_files over diff_text (or vice versa) purely on where its data lives.
All names are snake_case and self-describing, with a clear verb_noun pattern in diff_files, diff_text, inspect_file and apply_preview. Two names break the pattern — csv_diff (noun-first instead of diff_csv) and as_json_patch (prepositional) — which is a minor but noticeable inconsistency in an otherwise tight set.
Six tools is a well-scoped surface for a structural-diff server: each one covers a distinct input mode (files, text, CSV), a pre-flight check, or one direction of the patch lifecycle. No tool looks redundant or tacked on.
The lifecycle inspect -> diff -> generate patch -> preview patch is covered, with rich options for matching, tolerance and ignores across all supported formats. The notable gap is that nothing writes: apply_preview only previews, so patch application on disk (and any directory-level or multi-file diff) is a dead end an agent must work around.
Maintenance
Related MCP Connectors
Compare two JSON files deeply, ignoring order, to surface every difference. Get a clear, structure…
Exact text tools for AI agents: unified diff, patch apply, regex testing, grapheme counting.
Compare two JSON files deeply, regardless of order. Get a detailed difference report highlighting…
Compare two JSON files deeply without worrying about key or array order. Detect missing, extra, an…
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables deep, order-independent comparison of JSON files to detect differences including missing keys, value mismatches, and type differences. Provides detailed reports with path tracking for precise identification of variations between JSON structures.MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to compare documents, analyze changes, and retrieve document info using GroupDocs.Comparison. Supports various formats and includes licensing for production use.1MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to compare two texts line-by-line and receive a structured diff with additions, deletions, unchanged lines, and summary statistics, paid per call via x402 micropayments.1MIT
- FlicenseNot gradedqualityBmaintenanceEnables developers and AI agents to compute deterministic in-memory unified diffs between successive versions of live artifacts and receive structured change telemetry in return. It runs with zero external dependencies and plugs into MCP-compliant clients such as Claude Desktop, Cursor, and Windsurf.8-