Skip to main content
Glama

Diff Two Diagrams

diagrams_diff
Read-onlyIdempotent

Compare two diagram sources — two stored files, or a stored file against inline text — and report the added, removed, and renamed entity names in structured form.

Instructions

Compare two diagram sources — two stored files, or a stored file against inline text — and report the added, removed, and renamed entity names in structured form.

This is the review-time companion to diagrams_check_consistency: that tool asks whether a diagram still matches the code, this one asks what changed between two versions of the diagram itself. Give it the previous version as a_relative_path or a_content and the new version as the b side, and it lists what a reviewer needs to confirm. It is pure comparison over sources the store already knows how to read: no writes, no network, no filesystem changes.

Each side supplies exactly one of a path or inline content, so unstaged edits can be diffed without a round trip. Rename detection pairs a removed name with an added one only when they are identical once lowercased and stripped of separators, and every rename carries confidence: "heuristic" — similarity is not semantic identity.

With include_rename_evidence=true the existing rename pairs gain exact case-sensitive recognized diagram message-call counts for each old and new name on both sides. Repeated calls count separately. This scans diagram labels only and does not inspect source code or establish semantic identity. Evidence reports the first 100 pairs in rename order with pairs_available and pairs_capped. Either side above 10000 recognized calls refuses the entire enabled comparison. The evidence does not change rename pairing or is_same or enable call-order output.

Args:

  • include_rename_evidence (boolean, default false): Add bounded diagram call-label counts for paired rename names without changing matching or equality

  • compare_call_order (boolean, default false): Also compare recognized message-call names in order, preserving repetitions. Each side is capped at 10000 calls; over-limit comparison is refused. Plain labels, endpoints, arguments and control flow are excluded.

  • a_relative_path (string, optional): Side a as a path relative to the diagrams root

  • a_content (string, optional): Side a as inline source text (dialect detected from the source)

  • b_relative_path (string, optional): Side b as a path relative to the diagrams root

  • b_content (string, optional): Side b as inline source text (dialect detected from the source)

  • Exactly one path or content per side; both or neither is an error naming the side

Returns: JSON with schema: { "a": { "source": string, "type": "plantuml" | "mermaid" }, // path, or "" "b": { "source": string, "type": "plantuml" | "mermaid" }, "added": [{ "name": string }], // declared on b only "removed": [{ "name": string }], // declared on a only "renamed": [ // paired by the shared name normalizer { "from": string, "to": string, "confidence": "heuristic" } ], "unchanged": string[], // declared on both, in a's order "unchanged_count": number, "participants_added": string[], // sequence diagrams only; [] otherwise "participants_removed": string[], "calls_added": string[], "calls_removed": string[], "is_same": boolean, // entity names unchanged, and call order unchanged when comparison is enabled "call_order": { "a": string[], "b": string[], "changed": boolean }, // present only when compare_call_order=true "rename_evidence": { // present only when include_rename_evidence=true "pairs": [{ "from": string, "to": string, "a_from_calls": number, "a_to_calls": number, "b_from_calls": number, "b_to_calls": number, "confidence": "heuristic" }], "pairs_available": number, "pairs_capped": boolean, "pair_limit": 100, "call_limit": 10000, "basis": "diagram-message-call-labels" }, "confidence": "heuristic", "heuristic_warning": string }

A paired rename leaves the added/removed lists, so no change is reported twice. The two sides may use different dialects; each is read with its own syntax.

Examples:

  • Use when: "Did the order or repetition of message calls change?" -> compare_call_order=true with the two diagram sources

  • Use when: "What changed in this diagram since my last edit?" -> a_relative_path="models/order.puml", b_content=""

  • Use when: "Compare the stored diagram against the version in my buffer" -> a_relative_path="system/flow.mmd", b_content=""

  • Don't use when: You want to know whether the diagram still matches the code (use diagrams_check_consistency)

  • Don't use when: You want member-level, layout, or style differences (out of scope; this tool compares declared names only)

Error Handling:

  • CallOrderLimitError rejects enabled comparisons exceeding 10000 recognized calls on either side, without returning partial arrays or source text

  • Returns "Error: Invalid side 'a'|'b': supply exactly one of ..." when a side supplies both or neither of its path and content

  • Returns "Error: Invalid side 'a'|'b' content: not a recognizable ..." when inline content is neither PlantUML nor Mermaid

  • Returns "Error: No diagram found at ''" when a stored side does not exist

  • Returns "Error: Refused to access path outside the diagrams root" when a stored side attempts to escape the diagrams directory

  • Returns "Error: ... does not have a recognized diagram extension" when a stored path's extension is not .puml/.plantuml/.mmd/.mermaid

  • Unexpected internal failures return a generic "Error: Unexpected internal error ..." with isError:true and are logged to stderr without source, paths, or secrets

Input Schema

NameRequiredDescriptionDefault
a_contentNoSide a as inline source text (no file read). Exactly one of a_relative_path or a_content must be given; the dialect is detected from the source itself.
b_contentNoSide b as inline source text. Exactly one of b_relative_path or b_content must be given; the dialect is detected from the source itself.
a_relative_pathNoSide a as a stored diagram: path relative to the diagrams root (e.g. 'system/order-flow.puml'). Exactly one of a_relative_path or a_content must be given.
b_relative_pathNoSide b as a stored diagram: path relative to the diagrams root. Exactly one of b_relative_path or b_content must be given.
compare_call_orderNoCompare recognized message-call names in order, including repetitions (default: false). Plain labels, arguments, endpoints and control flow are not compared.
include_rename_evidenceNoInclude exact recognized diagram message-call counts for paired rename names (default: false). Limited to 100 pairs and 10000 calls per side. This is label evidence only and does not scan code or prove identity.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv0.11.0
    • addedInput schema / properties / include_rename_evidence
      Added value: +{
      +  "default": false,
      +  "description": "Include exact recognized diagram message-call counts for paired rename names (default: false). Limited to 100 pairs and 10000 calls per side. This is label evidence only and does not scan code or prove identity.",
      +  "type": "boolean"
      +}
  2. Addedv0.10.0

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive), and the description adds substantial context beyond them: no writes/network/filesystem access, heuristic-only rename confidence, bounded evidence (100 pairs, 10000-call refusal), and the guarantee that paired renames drop out of added/removed. Error taxonomy is enumerated with exact message shapes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose and the sibling contrast, and the Returns block earns its place since no output schema exists. The 'Args' section, however, largely restates input-schema descriptions verbatim, adding length without new information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given six parameters, no output schema, and a nontrivial comparison semantics, the description covers return shape, boundary conditions, refusal behavior, and error cases. Nothing an agent needs to invoke it correctly or interpret failures is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds real semantics: the exactly-one-of path/content rule per side, that each side's dialect is detected independently, and that include_rename_evidence does not alter pairing or is_same. Slight redundancy with the schema's own param text keeps it below 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource — 'Compare two diagram sources' — and immediately scopes the output to 'added, removed, and renamed entity names in structured form.' It also explicitly contrasts itself with the sibling diagrams_check_consistency, so an agent can distinguish the two without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit 'Use when' scenarios (call-order comparison, buffer-vs-stored diff) and 'Don't use when' exclusions that route to diagrams_check_consistency and declare member-level/layout/style differences out of scope. The a=previous / b=new convention is stated outright.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.