Skip to main content
Glama

DIAGRAMS MCP SERVER

Engineering documentation for a local first MCP server that keeps PlantUML and Mermaid diagrams beside the code they describe

The server gives an MCP client a controlled interface for reading and maintaining diagram source and for comparing that source with a codebase It also produces reviewable diagram drafts and rendered exports Source files remain the editable record of the architecture

PROJECT STATUS

The project is a technical preview This document describes version zero ten zero with fifteen tools

Version zero nine zero introduced diagrams_save_export and diagrams_scaffold The scaffold member and field type and named relationship modes described below are included in that version Check the installed package version when comparing its tool surface with main

Version zero ten zero adds nullable and array scaffold labels and corrects sequence sender ownership when caller names collide across files

The chart groups the fifteen tools by their primary purpose It describes the tool surface rather than project completion

pie showData
    accTitle: Tool categories
    accDescr: Five storage tools and three rendering tools and two analysis tools and four diagram drafting and template tools and one code drafting tool
    title Tool categories
    "Diagram storage" : 5
    "Rendering and sharing" : 3
    "Analysis and comparison" : 2
    "Diagram drafting and templates" : 4
    "Code drafting" : 1

The package declares Node 18 or newer as its runtime requirement Continuous integration checks Node 20 and Node 22 on Ubuntu and Windows The TypeScript compiler is a development dependency rather than a required production dependency

SYSTEM MODEL

An MCP client starts the server as a child process and exchanges protocol messages over standard input and standard output Startup diagnostics use standard error so they do not occupy the protocol stream

The project root defines the code analysis boundary The diagrams root defines the diagram storage boundary Custom template definitions are read separately beneath the project root These roots are resolved once when the server starts Diagram paths supplied to tools are relative to the diagrams root Code scopes supplied to analysis tools are relative to the project root

The architecture separates protocol handling from services and external resources Responses return through the tool adapter to the connected client

flowchart TB
    accTitle: System architecture
    accDescr: MCP requests pass through strict schemas and adapters to storage and analysis and rendering services
    client["MCP client"] <-->|stdio| server["CLI and MCP server"]
    server --> schemas["Strict input schemas"]
    schemas --> adapters["Tool adapters"]
    adapters --> store["Diagram storage"]
    adapters --> analysis["Analysis and generation"]
    adapters --> rendering["Rendering service"]
    store --> diagrams[("Diagrams root")]
    analysis --> code[("Project root")]
    rendering --> external["Local commands or opt in PlantUML endpoint"]

Tool adapters own protocol contracts and response formatting Services own filesystem operations and analysis and source generation Renderers invoke external command line tools through a separate command boundary Expected domain failures become tool errors Unexpected failures return a generic error and are logged through the shared error handling layer

INSTALLATION AND CLIENT CONNECTION

Install the published server with npm:

npm install -g diagrams-mcp-server

Run guided setup from the project directory:

diagrams-mcp-server setup

The setup workflow supports Claude Code and Codex and Cursor and VS Code and OpenCode and Antigravity It checks the selected client and project path before applying its supported configuration method Some clients require a manual command that setup prints for you

For a noninteractive Codex setup:

diagrams-mcp-server setup --client codex --yes

For a Cursor configuration pinned to the current project:

diagrams-mcp-server setup --client cursor --scope project --yes

Global scope is the default and leaves PROJECT_ROOT out of the server entry The server then uses the working directory supplied by the launching client Project scope places PROJECT_ROOT in the configuration so the server stays attached to one codebase An explicit --project-root also pins the root VS Code setup writes project configuration

After setup reload the client configuration and inspect its available tools Use diagrams_list to confirm the diagrams root before creating files An empty inventory is valid for a new project

Other stdio MCP clients can launch diagrams-mcp-server directly or use npx with arguments -y diagrams-mcp-server The server command accepts no tool requests through ordinary CLI arguments Tool calls travel through the MCP connection

For available startup and setup options:

diagrams-mcp-server --help
diagrams-mcp-server setup --help

CONFIGURATION AND RENDERING

PROJECT_ROOT selects the codebase used for analysis Its default is the server process working directory

DIAGRAMS_DIR selects the diagrams root Its default is the diagrams directory beneath PROJECT_ROOT A relative value is resolved beneath PROJECT_ROOT An absolute value selects a separate storage location Restart the server after changing either root

Rendering requires a working external renderer on PATH PlantUML uses the plantuml command Mermaid uses the mmdc command from the Mermaid CLI package The server package does not install either renderer for you External renderer packages have their own runtime requirements

To install the Mermaid command:

npm install -g @mermaid-js/mermaid-cli

PlantUML rendering prefers the local command When that command is missing remote fallback remains disabled unless ALLOW_REMOTE_PLANTUML is exactly true DISABLE_REMOTE_PLANTUML set to exactly true overrides that permission PLANTUML_SERVER_URL selects the remote endpoint when fallback is enabled The default endpoint is the public PlantUML rendering service

Remote fallback sends diagram source to the configured server Mermaid rendering always uses the local command A local renderer execution failure is an error rather than a reason to retry remotely Rendering uses temporary files that are cleaned up after the operation

Renderer selection follows the decision chart below Remote permission means ALLOW_REMOTE_PLANTUML is exactly true while DISABLE_REMOTE_PLANTUML is not true Only a missing local PlantUML command reaches that decision

flowchart TB
    accTitle: Renderer selection
    accDescr: Mermaid uses mmdc while PlantUML uses a local CLI or an explicitly permitted remote endpoint
    dialect{"Dialect"} -->|Mermaid| mermaid["Run local mmdc"]
    dialect -->|PlantUML| local{"Local plantuml command"}
    local -->|Available| plantuml["Run local plantuml"]
    local -->|Missing| permission{"Remote fallback allowed"}
    permission -->|No| failure["Return a render error"]
    permission -->|Yes| remote["Send source to configured endpoint"]

WORKING WITH DIAGRAMS

Start by discovering existing diagrams with diagrams_list Read the selected source with diagrams_get before proposing a change Use diagrams_diff to compare the existing source with a proposed revision Then apply the reviewed revision through diagrams_update Use diagrams_create for a new diagram and diagrams_delete for explicit removal

Create refuses an existing target Update operates on an existing diagram Storage validates recognized diagram extensions and source structure These checks establish basic dialect shape rather than full language correctness Use rendering and human review to inspect the resulting diagram

For a new architecture draft use diagrams_generate on a narrow code scope For a call flow draft use diagrams_generate_sequence For a blank design use diagrams_template These tools return source for review without saving a diagram Pass reviewed source to diagrams_create when you decide to persist it

Run diagrams_check_consistency after a code change to inspect declaration evidence for diagram entities Treat unmatched names as review prompts An unmatched name can reflect unsupported syntax or incomplete scanning rather than an architectural defect

This workflow connects the tools through explicit review steps The arrows describe a suggested user workflow rather than an automatic pipeline Generation and comparison do not save files on your behalf

flowchart TB
    accTitle: Diagram review workflow
    accDescr: Read or draft source then review and compare before explicitly saving and rendering and checking consistency
    stored["Read existing diagram source"] --> review["Review source"]
    draft["Generate or template a draft"] --> review
    review --> compare["Compare revisions when needed"]
    compare --> save["Explicit create or update"]
    save --> render["Render and inspect"]
    render --> check["Check consistency against code"]
    check -->|Revise when needed| review

TOOL CONTRACTS

Inventory and source access

diagrams_list supports type_filter and zero based offset pagination An explicit limit accepts 1 through 500 Omitting limit returns all remaining matches The response distinguishes the page count from the total and reports has_more so callers can continue without guessing

diagrams_get returns complete source unless max_chars requests a window An explicit window accepts 1 through 100000 UTF-16 code units The response reports offset and returned_chars and total_chars together with is_partial and has_more An offset beyond the source is an error

diagrams_create and diagrams_update and diagrams_delete are the explicit diagram mutation tools All fifteen tools in the current checkout reject unknown input arguments Clients should use the tool schemas exposed by MCP discovery as the exact argument reference

Related MCP server: jarbobo

Analysis and comparison

diagrams_check_consistency compares extracted diagram names with source declaration evidence and reports matched files and analyzer tiers Its extractors include language specific declaration patterns and a generic whole word fallback The optional TypeScript compiler improves selected analysis paths The result remains heuristic and does not establish runtime correctness

diagrams_diff accepts two sides Each side must provide exactly one stored path or inline source Inline source must identify a recognized diagram dialect Input shape is checked before either stored side is read

The default comparison reports added and removed names with heuristic rename pairing It does not compare layout or member signatures or resolved types Setting compare_call_order to true additionally compares recognized call names in source order while preserving repetitions That mode accepts at most 10000 recognized calls per side and fails above the ceiling rather than returning a partial comparison It does not establish runtime execution order

Diagram generation and templates

diagrams_generate returns a class diagram draft from source declarations It can include evidenced TypeScript inheritance and implementation edges when the optional compiler is available Without that support it returns declaration based output with an explicit note about unavailable relations It does not perform full type resolution

diagrams_generate_sequence returns a static call flow draft It reports unresolved callees rather than inventing participants Since version zero ten zero each sender stays tied to the file containing the call site even when another file declares the same caller name Callee lookup still uses the first case insensitive declaring participant Calls inside callbacks are conservatively treated as deferred and excluded from the ordered messages This policy is not a claim that every callback executes asynchronously include_call_parentheses changes message labels only

diagrams_template emits class or sequence or c4_context starter source in puml or mermaid format It accepts 1 through 20 unique ASCII identifier names of at most 60 characters each and an optional nonblank title of at most 200 characters

For project templates use template set to custom with a custom_template identifier Definitions are JSON files in the project root hidden directory named diagrams-templates with a leading dot Each filename is the identifier followed by the JSON extension The identifier accepts ASCII letters and digits and underscores and hyphens with a length from 1 through 64

A definition supports optional puml and mermaid sections Each supplied section requires source and entity strings The supported placeholders are {{title}} and {{entities}} and {{name}} Expansion is a single pass and does not evaluate code Definitions must be regular files rather than symbolic links The read ceiling is 65536 bytes and the expanded source ceiling is 1000000 UTF-16 code units

diagrams_list_templates discovers built in kinds and custom filename candidates without reading custom definition contents Discovery examines at most 1000 directory entries plus a lookahead entry Custom content is validated when diagrams_template instantiates it Discovery does not create a missing template directory

Rendering and sharing

diagrams_render returns SVG or PNG through the configured renderer diagrams_export returns a standalone HTML document without persisting the export target Both operations share the renderer selection policy described above

HTML exports embed SVG as a base64 image rather than inline SVG markup This isolates the image from the surrounding document but is not an SVG sanitizer Text within the rendered image is not selectable A restrictive content security policy limits the wrapper document

include_source defaults to true and embeds the escaped source in a collapsible section Setting it to false omits the source section entirely The finished HTML document must fit within 5000000 UTF-8 bytes Oversized exports fail instead of returning a partial document

diagrams_save_export saves the same HTML bundle beneath the diagrams root through an explicit output_path The target must use the HTML extension and must not already exist The size check runs before output directories or the output file are created The response contains acknowledgement and metadata rather than the HTML Saved HTML files do not become diagrams in the inventory or CRUD tools

TypeScript scaffolding from diagrams

diagrams_scaffold returns TypeScript source for review It reads one stored diagram and does not save or execute the proposed code The default output consists of empty exported classes derived from heuristic name candidates Invalid names and reserved names are skipped and reported An empty candidate set produces empty source

include_members enables a limited parser for plain top level multiline class blocks It emits fields as unknown and methods as throwing stubs Arguments and implementation behavior are not recovered

include_types implies include_members It preserves only string or number or boolean or bigint or an exactly emitted class name with an optional single array suffix Since version zero ten zero this mode also accepts exactly one null arm on either side of that type and emits the type followed by | null For example a field labeled string | null remains nullable in the draft The same mode accepts Array<T> and ReadonlyArray<T> labels T must be a supported primitive or an emitted class name The first form emits T[] and the second emits readonly T[] Both can have one null arm and neither accepts nested arrays or other generics Wrapper and nullable labels require colon field notation and fit within 82 characters Whitespace around the separator counts toward that limit Other unions and bare null remain unsupported Unsupported field labels remain unknown Accepted fields use definite assignment without supplying runtime values

include_relations implies both earlier modes It accepts labeled --> associations between explicitly declared plain classes that are also emitted The role label becomes a proposed field Supported target multiplicity can produce an array field Existing body members win over relation fields and accepted names keep their first occurrence The result does not recover ownership or enforce cardinality

Scaffolding defaults to 30 classes and permits at most 60 Each class accepts at most 30 emitted members Relation mode appends at most 300 relationship fields across the result Metadata distinguishes skipped candidates from cap related omissions Source above 1000000 UTF-8 bytes is refused after the stored file is read This ceiling limits processed input rather than the memory needed to read the original file

OPERATIONAL LIMITS AND FAILURE RECOVERY

Consistency and code generation scans examine at most 5000 source files Directory traversal skips hidden directories and known dependency and build directories such as node_modules and dist and build and out and target Only files with recognized code extensions are collected An unmatched name in an excluded file is outside that scan result Files above 1000000 bytes are skipped The scanners limit concurrent file reads to 32 Consistency evidence retains at most 10 matched file references per entity while reporting the full match count

Class generation defaults to 30 entities with a ceiling of 60 It emits at most 60 relations and omits edges whose endpoints were capped Sequence generation defaults to 8 participants and 20 messages Its ceilings are 20 participants and 50 messages Inspect truncated and scan_warning and the tool specific cap metadata before treating any result as complete

Local renderer commands have a default timeout of 20000 milliseconds Captured renderer streams are bounded at 1000000 characters each Since version zero nine zero local SVG and PNG image files are limited to 5000000 bytes before base64 encoding or HTML bundling Oversized image files are refused and the temporary render directory is removed Split or simplify the diagram before trying again Remote PlantUML requests also have a 20000 millisecond timeout and a 5000000 byte response ceiling Since version zero nine zero the timeout covers headers and the full body download and the byte ceiling is enforced as decoded chunks arrive Oversized or failed downloads are stopped and unused HTTP error bodies are discarded These bounds do not turn external renderers into an application sandbox

Tool execution failures are marked with isError set to true Schema rejection can occur before the handler runs A missing diagram should lead to a fresh inventory check An existing create target requires a new path or an intentional update An existing export target requires a different output path or explicit removal outside the export tool A missing renderer requires installing the command and checking PATH in the environment that launches the MCP client A capped scan should lead to a narrower scope before drawing conclusions

The storage and scope services reject paths that escape their configured roots and apply symbolic link checks at filesystem boundaries The server still runs with the operating system permissions of its process Treat diagram source and external renderer configuration as trusted inputs appropriate to that execution environment

SOURCE ORGANIZATION AND DEVELOPMENT

The src directory contains runtime source and colocated tests The tools directory beneath src holds one adapter per tool The services directory beneath src holds storage and analysis and rendering and export and scaffold modules The setup directory beneath src owns client configuration workflows The integration directory beneath src exercises MCP transport contracts

The scripts directory owns clean builds and compiled test discovery The dist directory is generated build output The docs directory holds detailed architecture and project handoff records The architecture document describes module ownership and request paths The roadmap document records completed milestones and future candidates The release checklist records package verification and publication steps CONTRIBUTING describes the contribution workflow RELEASE_NOTES records versioned changes The cleanup handoff and next features documents preserve historical context and should be read with their recorded scope and date

To work on the current source checkout run these commands from the repository root in order:

npm ci
npm run lint
npm run format:check
npm run build
npm test

Tests run from compiled output so build before running them The build removes stale output before compiling For a local MCP client configure node as the server command and supply the absolute path to the compiled index JavaScript file under dist as its argument Set PROJECT_ROOT to the codebase that this local server should analyze This local entry exercises the current source checkout The published setup command otherwise installs the published package through npx for its generated server entry

Running npm ci in the checkout also supplies the development TypeScript compiler for compiler backed analysis Published installs normally use the fallback extractors Installing TypeScript only in the analyzed project does not guarantee that the server package can resolve it

Continuous integration runs lint and formatting checks and a build and an entry point help check before the test suite Renderer behavior is covered through controlled dependencies without requiring global renderer installations or network rendering in the test jobs External renderer installation still needs validation in the intended runtime environment

When extending the project keep tool schemas and response metadata explicit Place reusable behavior in the owning service and preserve filesystem scope checks at every new storage boundary Cover observable behavior through focused tests and update the relevant engineering documentation in the same change

LICENSE

Released under the MIT license See LICENSE for the full terms

Available Tools

15 tools
diagrams_check_consistencyCheck Diagram-to-Code ConsistencyA
Read-onlyIdempotent

Compare class/interface/component names mentioned in a PlantUML or Mermaid diagram against identifiers that actually exist in the codebase, to catch documentation drift.

This is a heuristic, text-based check (not a full semantic/AST analysis): it extracts entity names from class/interface/enum/component declarations in the diagram, then searches source files under the project root for a matching identifier as a whole word. It flags names that appear in the diagram but were not found anywhere in the scanned code — a signal the diagram may be outdated, or the code was renamed/removed/not yet built.

This tool does NOT modify the diagram or the code. It only reports findings; the caller (agent or human) decides what to do about them.

Args:

  • relative_path (string): Path to the diagram to check, relative to the diagrams root

Returns: JSON with schema: { "diagram_path": string, "entities_found": number, // total entity names extracted from the diagram "entities_matched": number, // how many were found somewhere in the code "entities_unmatched": number, // how many were NOT found (potential drift) "files_scanned": number, // how many source files were searched "searched_directory": string, // absolute path of the code root that was scanned "truncated": boolean, // true when the 5,000-file scan cap was reached; unmatched results may be incomplete "scan_limit": number, // maximum source files collected during the scan "scan_warning": string | null, // human-readable warning when truncated, otherwise null "entities": string[], // extracted entity names, in extraction order "matched_entities": string[], // extracted entities found in the code "unmatched_entities": string[],// extracted entities NOT found (potential drift) "analyzers": { // scanned file extensions per analyzer tier "reliable": string[], // per-language declaration patterns (JS/TS, Python, PHP, Java) "experimental": string[], // generic heuristic path (C#, Go, Ruby, Kotlin, Rust) "generic": string[] // other scanned extensions, heuristic path only }, "confidence": "heuristic", // results are evidence, never a definitive verdict "heuristic_warning": string, // human-readable limits of the heuristic "evidence": [ // per-entity evidence, same order as "entities" { "name": string, "matched": boolean, "analyzers": ("reliable" | "experimental" | "generic")[], "matched_files": string[], // POSIX paths relative to searched_directory (capped) "matched_file_count": number } ], "issues": [ { "name": string, // the unmatched entity name "issue": string, // human-readable explanation "severity": "warning" | "info" } ] }

Examples:

  • Use when: "Is this class diagram still accurate compared to the code?" -> relative_path="models/user-class.puml"

  • Use when: Reviewing a PR that touches architecture, to check the UML docs weren't left behind

  • Don't use when: The diagram has no class/interface/component declarations (e.g. a pure sequence diagram) — entities_found will be 0, which is expected, not an error

Error Handling:

  • Returns "Error: No diagram found at ''" if the diagram file doesn't exist

  • An empty "issues" array with entities_found=0 means no checkable entities were found in the diagram, not that everything matched

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

ParametersJSON Schema
NameRequiredDescriptionDefault
relative_pathYesPath to the diagram to check, relative to the diagrams root.

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true and destructiveHint=false; the description reinforces this by stating 'This tool does NOT modify the diagram or the code.' Beyond that, it discloses the heuristic, text-based nature, the 5,000-file scan cap, truncation behavior, confidence level, and the distinction between reliable/experimental/generic analyzers. This exceeds what annotations alone convey.

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?

The description is lengthy, but it is well-structured with clear sections (overview, args, returns, examples, error handling) and front-loads the purpose and key non-modifying constraint. Every section adds value, though the inline return schema is verbose. Slightly overlong but organized enough to earn a 4.

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?

The description is exceptionally complete for a heuristic check tool: it covers the return schema in detail, error handling, edge cases (entities_found=0, truncation), and the confidence level. Despite having no output schema annotation, the description fully specifies the expected JSON structure and all relevant failure modes, leaving no ambiguity for an agent.

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

Parameters3/5

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

Schema coverage is 100% and the only parameter (relative_path) is already described as 'Path to the diagram to check, relative to the diagrams root.' The description adds example paths and clarifies the root relative interpretation, but these are marginal additions beyond the schema. The baseline of 3 applies since the schema carries the semantic load.

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?

The description clearly states the tool compares entity names in diagrams against code identifiers to catch documentation drift. It names the specific resource (PlantUML/Mermaid diagrams vs codebase) and distinguishes itself from sibling tools like diagrams_get or diagrams_render by focusing on consistency checking, not creation, retrieval, or rendering.

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 when-to-use scenarios ('Is this class diagram still accurate?', PR review) and a concrete don't-use condition (pure sequence diagram with no declarations, where entities_found=0 is expected). Also clarifies that an empty issues array with entities_found=0 means no checkable entities, not a pass, preventing misinterpretation.

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

diagrams_createCreate New DiagramA

Create a new PlantUML or Mermaid diagram file under the diagrams root.

The diagram type is inferred from the file extension in relative_path:

  • .puml or .plantuml -> PlantUML

  • .mmd or .mermaid -> Mermaid

This tool refuses to overwrite an existing file — use diagrams_update for that. Intermediate directories in relative_path are created automatically.

Performs a basic, dependency-free syntax check before writing (not full validation): PlantUML must include @startuml/@enduml boundaries; Mermaid must start with a known diagram declaration. Clearly invalid or empty sources are rejected without creating a file.

Args:

  • relative_path (string): Path for the new file, relative to the diagrams root, with a recognized extension

  • content (string): Full diagram source text

Returns: JSON with schema: { "relative_path": string, "created": true }

Examples:

  • Use when: "Create a class diagram for the User model" -> relative_path="models/user-class.puml", content="@startuml\nclass User {\n +id: int\n}\n@enduml"

  • Don't use when: The file already exists and you want to change it (use diagrams_update instead)

Error Handling:

  • Returns "Error: ... already exists" if a file already exists at relative_path

  • Returns "Error: ... does not have a recognized diagram extension" if the extension isn't one of .puml/.plantuml/.mmd/.mermaid

  • Returns "Error: Invalid PlantUML diagram (basic check): ..." if PlantUML source is empty or missing @startuml/@enduml boundaries

  • Returns "Error: Invalid Mermaid diagram (basic check): ..." if Mermaid source is empty or has no recognized diagram declaration

  • Returns "Error: Refused to access path outside the diagrams root" if relative_path attempts to escape the diagrams directory

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

ParametersJSON Schema
NameRequiredDescriptionDefault
contentYesFull PlantUML or Mermaid source text for the diagram.
relative_pathYesPath for the new diagram, relative to the diagrams root, including extension (.puml, .plantuml, .mmd, or .mermaid). E.g. 'system/order-flow.puml'.

TDQS

A4.9/5.0
Behavior5/5

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

Annotations only indicate non-readOnly, non-idempotent, non-destructive behavior. The description goes far beyond this by disclosing that it refuses to overwrite, creates intermediate directories automatically, performs a basic non-validating syntax check, rejects invalid/empty sources without creating files, prevents path escape, and logs unexpected errors safely without leaking secrets.

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

Conciseness5/5

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

The description is well structured: purpose first, then extension rules, overwrite policy, validation behavior, arg definitions, return shape, examples, and error handling. It is long but every section earns its place and the most decision-relevant information is front-loaded.

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?

For a creation tool with no output schema, the description fully compensates by specifying the exact return JSON structure, listing all expected error messages, and providing concrete usage examples. An agent has everything needed to invoke it correctly and anticipate failure modes.

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?

The input schema already describes both parameters fully (100% coverage). The description adds value by clarifying the extension-to-type mapping, the meaning of a recognized extension, automatic creation of intermediate directories, and the syntax-check behavior, which give the agent practical context for constructing valid parameter values.

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?

The description states a specific verb ('Create'), a specific resource ('PlantUML or Mermaid diagram file under the diagrams root'), and the inference rule from the file extension. It clearly distinguishes this tool from diagrams_update by explicitly saying it refuses to overwrite existing files.

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?

The description gives explicit usage context: use for creating new diagrams, and explicitly says not to use it when the file exists and needs changing, naming diagrams_update as the alternative. The included examples of when and when not to use it make the decision easy for an agent.

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

diagrams_deleteDelete DiagramA
Destructive

Delete a single PlantUML or Mermaid diagram file from the diagrams root.

This is destructive and cannot be undone — the file is removed from disk. To replace content instead, use diagrams_update. To remove then recreate with different content, delete first, then use diagrams_create.

Args:

  • relative_path (string): Path to the diagram relative to the diagrams root, as returned by diagrams_list

Returns: JSON with schema: { "relative_path": string, "deleted": true }

Examples:

  • Use when: "Remove the outdated order-flow diagram" -> relative_path="system/order-flow.puml"

  • Don't use when: You want to change the diagram content but keep the file (use diagrams_update)

Error Handling:

  • Returns "Error: No diagram found at ''" if the file doesn't exist

  • Returns "Error: Refused to access path outside the diagrams root" if relative_path attempts to escape the diagrams directory (e.g. via '../..')

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

ParametersJSON Schema
NameRequiredDescriptionDefault
relative_pathYesPath to the diagram to delete, relative to the diagrams root (e.g. 'system/order-flow.puml'). Get this from diagrams_list.

TDQS

A4.9/5.0
Behavior5/5

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

Beyond the destructiveHint=true annotation, the description discloses that deletion is physical and irreversible ('file is removed from disk'), details error responses for missing files and path traversal attempts ('Refused to access path outside the diagrams root'), and clarifies how internal failures are logged without leaking sensitive data. This is rich behavioral context that annotations alone do not provide.

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

Conciseness5/5

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

The description is longer than average, but every section earns its place: purpose, destructiveness warning, alternatives, args, return shape, examples, and error handling. The most critical facts (destructive, irreversible) are front-loaded, and the structured sections make the content easy for an agent to parse.

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?

For a destructive one-parameter tool with no structured output schema, the description is fully complete. It includes the return JSON shape, all relevant error cases, path safety constraints, and sibling-tool alternatives, so an agent has everything needed to invoke it correctly and predict consequences.

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; the description's Args section largely repeats the schema. However, the error-handling section and examples add meaning beyond the schema by clarifying that paths must come from diagrams_list and that escaping the diagrams root is refused, giving the agent a better model of valid and invalid inputs.

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?

The description opens with a specific verb and resource: 'Delete a single PlantUML or Mermaid diagram file from the diagrams root.' It clearly distinguishes the tool from siblings by explicitly naming diagrams_update and diagrams_create as alternatives for different goals, so an agent can select it correctly without opening schemas.

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?

The description gives explicit when-to-use and when-not-to-use guidance: replace content -> use diagrams_update; remove and recreate -> delete then create. It also provides concrete examples ('Remove the outdated order-flow diagram') and a 'Don't use when' clause, making the decision boundary unambiguous.

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

diagrams_diffDiff Two DiagramsA
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.

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.

Args:

  • 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 "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

ParametersJSON 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.

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already declare the safe-read profile, but the description adds substantial context beyond them: the heuristic rename rule and its 'similarity is not semantic identity' caveat, the 10000-call cap and the refusal to return partial arrays, root-escape and extension refusals, and the fact that a paired rename is removed from added/removed so nothing is reported twice. It also explicitly aligns with the annotations ('no writes, no network, no filesystem changes').

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 purpose, then routing, args, returns, examples, errors in a predictable order. The embedding of the full return schema is justified because no output schema exists, but the Args block largely duplicates the input schema and costs a few lines that don't earn their place.

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?

For a 5-parameter comparison tool with no output schema and no annotations gap, the description covers inputs, a full response shape, rename/limit edge behavior, and a complete error catalogue including the root-escape guard. An agent has everything needed to call it correctly and interpret failures.

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, and the description earns above that by adding semantics the schema lacks: the exact rename normalization (lowercased, separators stripped), what compare_call_order excludes (labels, endpoints, arguments, control flow), and the per-side cap. It only restates the path/content descriptions verbatim in the Args block, which is the one redundant piece.

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 ... report the added, removed, and renamed entity names') and immediately scopes it against the sibling diagrams_check_consistency. An agent can distinguish this from every other diagrams_* tool 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.

Usage Guidelines5/5

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

Provides explicit Use-when triggers with concrete invocations (call-order changes, last-edit diff, buffer vs stored) plus two Don't-use-when exclusions that name the alternative tool and the out-of-scope difference classes. Nothing is left to inference.

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

diagrams_exportExport Diagram as a Self-Contained HTML FileA
Read-onlyIdempotent

Package a stored PlantUML or Mermaid diagram and its rendered SVG into one self-contained HTML file you can share or open outside the repo. The SVG is encoded as a data image, so renderer markup is not parsed into the HTML DOM. SVG image processing disables scripts and external resource loading. A restrictive content security policy allows only data images and inline wrapper styles. SVG text is not selectable in the exported image. Diagram source is escaped in a native collapsible block when include_source is set, and the artifact works offline without new dependencies.

Rendering uses the same path and the same rules as diagrams_render: Mermaid requires the local 'mmdc' CLI with no fallback, and PlantUML prefers a local 'plantuml' CLI, falling back to the configured remote server only when ALLOW_REMOTE_PLANTUML=true and DISABLE_REMOTE_PLANTUML is not 'true'. Remote PlantUML rendering sends diagram source to that server over HTTPS.

The tool never writes a file: the HTML comes back as text and you decide where it lands. A bundle larger than 5000000 bytes is refused outright rather than cut down, because a half-rendered artifact is worse than none.

Args:

  • relative_path (string, required): Path to the diagram, relative to the diagrams root

  • include_source (boolean, default true): Embed the diagram source in a collapsible block

Returns: The HTML as a text content block, plus a JSON summary: { "relative_path": string, // POSIX form, the only path in the bundle "diagram_type": "plantuml" | "mermaid", "format": "html", "bytes": number, // UTF-8 byte length of the returned HTML "svg_chars": number, // image source characters after XML preamble stripping, before base64 encoding "source_included": boolean, // whether the source block was embedded "truncated": false, // always false; over-cap is an error, never a cut file "rendered_with": "local-plantuml" | "remote-plantuml" | "mmdc" }

Examples:

  • Use when: "Package the order-flow diagram so I can send it to someone without the repo" -> relative_path="system/order-flow.puml"

  • Use when: "Give me a standalone HTML of the checkout sequence" -> relative_path="system/checkout.mmd", include_source=false

  • Don't use when: You want the image alone (use diagrams_render, which returns an image block)

  • Don't use when: You want to edit the diagram (use diagrams_get and diagrams_update)

Error Handling:

  • Returns "Error: Local renderer image exceeded the 5000000-byte limit..." for oversized local SVG output before HTML bundling

  • Returns "Error: No diagram found at ''" if the diagram does not exist, before any render is attempted

  • Returns "Error: Mermaid rendering requires the 'mmdc' CLI..." when rendering a Mermaid diagram without mmdc installed (no fallback exists)

  • Returns "Error: PlantUML rendering requires a local 'plantuml' CLI..." when no local CLI is installed and remote rendering is not explicitly enabled (set ALLOW_REMOTE_PLANTUML=true to opt in)

  • Returns "Error: PlantUML rendering server responded with ..." when the opt-in remote fallback answers non-2xx

  • Returns "Error: The export bundle for '' is bytes, larger than the 5000000-byte limit, so it was not returned..." when the finished bundle exceeds the cap

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

ParametersJSON Schema
NameRequiredDescriptionDefault
relative_pathYesPath to the diagram to export, relative to the diagrams root.
include_sourceNoEmbed the diagram source in a collapsible block so the artifact explains itself (default: true). The block is a native <details> element, so it works without JavaScript.

TDQS

A4.7/5.0
Behavior5/5

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

With readOnly/destructive/idempotent annotations already covering the safety profile, the description adds substantial context beyond them: it never writes a file, the result is returned as text, the 5000000-byte cap is enforced as an error not truncation, remote PlantUML rendering requires ALLOW_REMOTE_PLANTUML=true, and Mermaid has no fallback without mmdc. It also discloses security behavior such as data-image encoding, CSP restrictions, and disabled script/external-resource loading. These are meaningful operational traits not present in the structured annotations.

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

Conciseness5/5

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

The description is front-loaded with the core purpose, then moves through rendering rules, return behavior, args, examples, and errors in a structured way. Although detailed, the length matches the complexity of the tool and each section earns its place by covering a distinct operational concern.

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?

There is no output schema, but the description fully documents the returned text and JSON summary fields, as well as expected error messages and the 5000000-byte cap. Combined with annotations that cover safety hints, the definition gives an agent everything needed to invoke the tool correctly.

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

Parameters3/5

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

Schema description coverage is 100%, so the input schema already documents both parameters. The description's Args section largely repeats relative_path and include_source semantics, adding only minor context about the collapsible block and default. The baseline of 3 is appropriate when the schema carries the parameter documentation.

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?

The first sentence states a specific verb and resource: package a stored PlantUML or Mermaid diagram plus rendered SVG into a self-contained HTML file. It distinguishes the tool from siblings by later naming diagrams_render for image-only output and diagrams_get/diagrams_update for editing. An agent can identify it as the export-to-HTML tool without opening another 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?

The Examples section gives explicit 'Use when' cases and 'Don't use when' cases with named alternatives: diagrams_render for an image alone and diagrams_get/diagrams_update for edits. This leaves no ambiguity about when to select this tool versus sibling tools.

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

diagrams_generateGenerate a Class Diagram from CodeA
Read-onlyIdempotent

Draft a PlantUML or Mermaid class diagram from a slice of the codebase, returning source text to review and then save with diagrams_create.

This is the generative flip side of diagrams_check_consistency: the same code-reading machinery that detects drift can seed the diagram in the first place. It reads class/interface/enum/type/function declarations under the requested scope and emits one box per declared name, plus extends/implements edges when the TypeScript AST can evidence them. It never writes: nothing lands in the diagrams directory without an explicit diagrams_create call.

It is a heuristic (name extraction, not full type modeling) and says so in every result: member lists, generics, package nesting, and cross-file inheritance through re-exports are out of scope, and a scope without TypeScript-family files yields entities with no relations.

Args:

  • scope (string, default "."): Relative path under the project root pointing at a file or a directory. Absolute paths and anything resolving outside the project root are refused

  • format ('puml' | 'mermaid', default 'puml'): Output dialect

  • max_entities (integer 1-60, default 30): Hard cap on emitted declarations

  • include_relations (boolean, default true): Emit extends/implements edges when evidence is available

Returns: JSON with schema: { "scope": string, // POSIX path as resolved, "." for the project root "format": "puml" | "mermaid", "source": string, // the generated diagram; identical to the text block "entities": string[], // declared names in emission order, capped "entities_included": number, // length of "entities" "entities_available": number, // distinct names found, may exceed the cap "entities_capped": boolean, // true when names were dropped by the cap "entity_limit": number, // the applied cap (max_entities, at most 60) "relations": [ // evidenced edges only; empty when evidence is unavailable { "from": string, "to": string, "kind": "extends" | "implements" } ], "relations_included": number, "relations_available": number, "relations_capped": boolean, // true when edges were dropped by the cap or by an entity the cap removed "relation_limit": number, // 60 "files_scanned": number, "truncated": boolean, // true when the 5,000-file scan cap was reached "scan_limit": number, // 5,000 "scan_warning": string | null, // human-readable warning when truncated, otherwise null "dialect_note": string | null, // non-null when relations are unavailable or the scope has no code files "confidence": "heuristic", "heuristic_warning": string, // what name extraction can and cannot tell you "written": false // always false; save with diagrams_create }

Every cap reports itself in-band, so a truncated or capped result is never silent.

Examples:

  • Use when: "Draft a class diagram for the services layer" -> scope="src/services"

  • Use when: "Give me a Mermaid starter for this module" -> scope="src/models", format="mermaid"

  • Don't use when: You want a hand-written skeleton instead of one read from code (write the source directly, or use diagrams_create)

  • Don't use when: You expect semantic accuracy (member types, generics, or resolved cross-file inheritance); this is a heuristic draft

Error Handling:

  • Returns "Error: Refused to resolve scope outside the project root: ''" when scope is absolute or resolves outside the project root; no file is read

  • A scope with no code files is not an error: entities is empty with a dialect_note explaining why

  • Emitted source always passes the same syntax gate diagrams_create enforces; an emission that cannot is reported as an unexpected internal error

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

ParametersJSON Schema
NameRequiredDescriptionDefault
scopeNoRelative path under the project root pointing at a file or a directory to read (default: '.', the whole project root). Absolute paths and anything that resolves outside the project root are refused..
formatNoOutput dialect for the generated class diagram (default: 'puml').puml
max_entitiesNoHard cap on emitted class/interface declarations, an integer between 1 and 60 (default: 30). The applied cap is reported as entity_limit; anything past it is counted in entities_available and flagged by entities_capped.
include_relationsNoEmit 'A <|-- B' / 'A <|.. B' extends/implements edges when relation evidence is available (default: true). Relations are read from TypeScript heritage clauses only, so a scope without TypeScript-family files emits an empty relations list with a dialect_note.

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already cover readOnly/idempotent/non-destructive, but the description adds substantial beyond them: it never writes ('written: false'), it is a name-extraction heuristic with stated blind spots (members, generics, re-exports), all caps report in-band, and error/refusal behavior is spelled out including out-of-root scope refusal.

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, then evidence, limits, args, returns and errors in a scannable order. It is long and the Args section substantially duplicates the schema, which costs a point, but no sentence is filler.

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?

There is no output schema, yet the description inlines the full JSON return shape with per-field comments, so an agent knows exactly what comes back, including truncation flags and confidence. Error cases and the no-code-files non-error path are also covered.

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 operational meaning: scope refusal semantics, the TypeScript-only source of relations, and the cap/entity_limit reporting relationship. It largely mirrors the schema in the Args section, so it adds context rather than new parameter detail.

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 (generate/draft) and resource (PlantUML/Mermaid class diagram from a codebase slice), and explicitly positions itself against two siblings: diagrams_create (saving) and diagrams_check_consistency (drift detection). An agent can pick 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.

Usage Guidelines5/5

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

Provides concrete 'Use when' and 'Don't use when' entries with examples, names the sibling alternative (diagrams_create) for hand-written skeletons, and sets expectations against the heuristic limitation. Routing is fully determined.

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

diagrams_generate_sequenceGenerate a Sequence Diagram from CodeA
Read-onlyIdempotent

Draft a PlantUML or Mermaid sequence diagram from the message-call patterns in a slice of the codebase, returning source text to review and then save with diagrams_create.

Static call-site order is not runtime order. This tool reads call sites in the order a reader meets them and says so in every result: a call inside a callback, promise, or listener is counted in deferred_count and excluded from the messages, because its real position in the conversation is unknowable from source.

It is the generative flip side of the consistency checker's ordered call graph: the same caller-to-callee evidence, turned into a starter diagram instead of a verdict. It never writes: nothing lands in the diagrams directory without an explicit diagrams_create call.

Each sender is the file containing the call site even when another file declares the same caller name. Callee mapping uses case-insensitive declared-identifier equality and the first declaring participant in file order. A callee that no file in the scope declares is reported in unresolved_callees, never attached to an invented participant. Which class owns a method is a type question, and out of scope.

Args:

  • scope (string, default "."): Relative path under the project root pointing at a file or a directory. Absolute paths and anything resolving outside the project root are refused

  • format ('puml' | 'mermaid', default 'puml'): Output dialect

  • max_participants (integer 1-20, default 8): Hard cap on declared participants

  • max_messages (integer 1-50, default 20): Hard cap on emitted messages

  • include_call_parentheses (boolean, default false): When true, emitted message labels append '()' in both dialects; structured messages.message values stay bare

Returns: JSON with schema: { "scope": string, // POSIX path as resolved, "." for the project root "format": "puml" | "mermaid", "source": string, // the generated sequence; identical to the text block (message labels carry '()' when include_call_parentheses is true) "participants": string[], // participant names as emitted, in first-conversation order, capped "participants_included": number, // length of "participants" "participants_available": number,// distinct participants in candidate messages, may exceed the cap "participants_capped": boolean, // true when participants were dropped by the cap "participant_limit": number, // the applied cap (max_participants, at most 20) "messages": [ // ordered call sites, one per sequenced call (message stays bare when include_call_parentheses is true) { "from": string, "to": string, "message": string, "line": number, "via_callback": false } ], "messages_included": number, "messages_available": number, // candidate messages, may exceed the cap "messages_capped": boolean, // true when messages were dropped by either cap "message_limit": number, // the applied cap (max_messages, at most 50) "deferred_count": number, // call sites inside callbacks/promises: counted, never sequenced "unresolved_callees": string[], // callees no participant in the scope declares "files_scanned": number, "truncated": boolean, // true when the 5,000-file scan cap was reached "scan_limit": number, // 5,000 "scan_warning": string | null, // human-readable warning when truncated, otherwise null "confidence": "heuristic", "heuristic_warning": string, // what static call order can and cannot tell you "written": false // always false; save with diagrams_create }

Every cap reports itself in-band, so a truncated or capped result is never silent.

Examples:

  • Use when: "Show the call flow between the checkout and payment modules" -> scope="src/checkout"

  • Use when: "Draft a Mermaid sequence for this service layer" -> scope="src/services", format="mermaid"

  • Don't use when: You need runtime ordering, async semantics, or which class a method belongs to (out of scope; deferred and unresolved calls are reported instead)

  • Don't use when: You want a class diagram (use diagrams_generate) or a hand-written skeleton (write the source directly)

Error Handling:

  • Returns "Error: Refused to resolve scope outside the project root: ''" when scope is absolute or resolves outside the project root; no file is read

  • A scope with no code files is not an error: participants and messages are empty, and the emitted source is a valid empty diagram

  • Emitted source always passes the same syntax gate diagrams_create enforces; an emission that cannot is reported as an unexpected internal error

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

ParametersJSON Schema
NameRequiredDescriptionDefault
scopeNoRelative path under the project root pointing at a file or a directory to read (default: '.', the whole project root). Absolute paths and anything that resolves outside the project root are refused..
formatNoOutput dialect for the generated sequence diagram (default: 'puml').puml
max_messagesNoHard cap on emitted messages, an integer between 1 and 50 (default: 20). The applied cap is reported as message_limit; messages past it, or to a participant the participant cap removed, are counted in messages_available and flagged by messages_capped.
max_participantsNoHard cap on declared participants, an integer between 1 and 20 (default: 8). The applied cap is reported as participant_limit; anything past it is counted in participants_available and flagged by participants_capped.
include_call_parenthesesNoWhen true, emitted message labels append '()' in both dialects (default: false). Structured messages.message values stay bare.

TDQS

A4.6/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, closed-world), so the description is free to add what they cannot: it never writes, static call order is not runtime order, deferred callback calls are counted but never sequenced, undeclared callees go to unresolved_callees rather than an invented participant, every cap reports itself in-band, and a 5,000-file scan cap exists. Error behavior (scope refusal, empty-scope non-error, syntax gate) is disclosed in detail.

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?

Purpose, scope constraint, and hand-off are front-loaded in the first three sentences, and the Returns/Error Handling sections genuinely earn their space because there is no output schema. The Args block, however, duplicates schema descriptions that are already at 100% coverage, which is the only real padding.

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?

For a no-output-schema tool with five parameters and a complex heuristic result, the description supplies the full return shape (participants/messages caps, deferred_count, unresolved_callees, confidence, written), worked examples, and error semantics. Nothing an agent needs to invoke or interpret it is missing.

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

Parameters3/5

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

Schema description coverage is 100% and the schema already documents defaults, ranges, and the meaning of include_call_parentheses' bare structured messages. The description's Args block largely restates those entries verbatim, so it adds only cross-references to the return fields (message_limit, participants_capped) rather than new parameter meaning. Baseline 3 is correct when the schema does the heavy lifting.

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 — 'Draft a PlantUML or Mermaid sequence diagram from the message-call patterns in a slice of the codebase' — and immediately names the sibling it hands off to (diagrams_create) and the sibling it contrasts with (diagrams_generate, class diagrams). An agent can distinguish it from the other 14 diagrams_* tools 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.

Usage Guidelines5/5

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

Provides explicit 'Use when' / 'Don't use when' blocks with worked examples (scope="src/checkout", format="mermaid"), names the alternative for class diagrams, and states the exclusion for runtime ordering, async semantics, and class ownership. Routing is unambiguous.

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

diagrams_getGet Diagram SourceA
Read-onlyIdempotent

Retrieve the raw source text of a single PlantUML or Mermaid diagram, in full or as an explicit character window.

Args:

  • relative_path (string): Path to the diagram relative to the diagrams root, as returned by diagrams_list

  • offset (number, optional): Zero-based character offset where the returned window starts (default: 0)

  • max_chars (number, optional): Maximum characters to return from offset (1-100000). Omit to return the full source

Returns: JSON with schema: { "relative_path": string, "type": "plantuml" | "mermaid", "content": string, // full source, or the requested [offset, offset+max_chars) window "is_partial": boolean, // true when content is a window rather than the full source "offset": number, // effective character offset of this window "total_chars": number, // full source length in characters "returned_chars": number,// length of the returned content "has_more": boolean // true when source after this window remains }

The text block always equals structuredContent.content. Content is never silently truncated: omitting offset/max_chars returns everything, and requesting a window is always reported via is_partial/has_more.

Examples:

  • Use when: "Show me the order-flow diagram" -> relative_path="system/order-flow.puml"

  • Use when: "Read the first 2000 characters of the big diagram" -> relative_path="...", offset=0, max_chars=2000, then offset=2000 for the next window

  • Don't use when: You need to list what diagrams exist first (use diagrams_list)

Error Handling:

  • Returns "Error: No diagram found at ''" if the file doesn't exist

  • Returns "Error: Refused to access path outside the diagrams root" if relative_path attempts to escape the diagrams directory (e.g. via '../..')

  • Returns "Error: Invalid source window: ..." if offset/max_chars are negative, non-integer, or max_chars is outside 1-100000

  • Returns "Error: offset is out of range ..." if offset points past the end of the source

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

ParametersJSON Schema
NameRequiredDescriptionDefault
offsetNoZero-based character offset into the diagram source where the returned window starts (default: 0).
max_charsNoMaximum characters to return starting at offset (1-100000). Omit to return the full source.
relative_pathYesPath to the diagram, relative to the diagrams root (e.g. 'system/order-flow.puml'). Get this from diagrams_list.

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false. The description adds substantial behavioral detail beyond this: it explains the windowing behavior with is_partial/has_more flags, guarantees no silent truncation, and provides a comprehensive error-handling list (file not found, path escape, invalid window, out-of-range offset). This far exceeds annotation coverage and fully discloses behavior.

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

Conciseness5/5

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

While long, the description is modularly structured with clear sections (Args, Returns, Examples, Error Handling) and front-loads the core purpose. Every sentence serves a purpose—there is no fluff or repetition. The length is justified by the tool's windowing and error complexity, and the structure makes it easy to scan.

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?

Despite lacking an output schema, the description provides a full inline JSON return schema with all fields explained. It covers error cases, examples, and parameter usage. For a tool with this complexity (character windows, partial returns), the description leaves nothing an agent needs to call it correctly; it is complete.

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 description coverage is 100%, so the baseline is 3. The description reinforces each parameter and adds usage nuance: it explains that omitting offset/max_chars returns the full source, demonstrates a windowing example (offset=0, max_chars=2000, then offset=2000), and clarifies the zero-based offset. This goes beyond the schema's basic type/range descriptions, though it does not introduce entirely new semantics.

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?

The description opens with a precise verb+resource statement: 'Retrieve the raw source text of a single PlantUML or Mermaid diagram, in full or as an explicit character window.' It clearly distinguishes itself from siblings, explicitly noting the alternative diagrams_list for listing diagrams. No ambiguity about what this tool does.

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?

The Examples section explicitly states 'Use when' scenarios (e.g., 'Show me the order-flow diagram') and 'Don't use when' (e.g., when needing to list diagrams first, use diagrams_list). It also instructs that relative_path should come from diagrams_list, giving clear routing to the correct sibling.

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

diagrams_listList Architecture DiagramsA
Read-onlyIdempotent

List all PlantUML and Mermaid diagram files stored under the project's diagrams directory.

This tool scans the configured diagrams root recursively and returns every file with a recognized diagram extension (.puml, .plantuml, .mmd, .mermaid). It does NOT create, modify, or render diagrams — read-only.

Args:

  • type_filter ('plantuml' | 'mermaid' | 'all'): Restrict results to one diagram type (default: 'all')

  • offset (number, optional): Zero-based number of matching diagrams to skip (default: 0)

  • limit (number, optional): Maximum diagrams to return (1-500). Omit to return every remaining match

Returns: JSON with schema: { "diagrams_root": string, // absolute path being scanned "count": number, // number of diagrams in this page "total": number, // number of diagrams matching type_filter, before paging "offset": number, // effective offset of this page "limit": number, // effective limit of this page (requested limit, or remaining count when omitted) "has_more": boolean, // true when diagrams after this page remain "diagrams": [ { "relative_path": string, // path to use with diagrams_get / diagrams_update "type": "plantuml" | "mermaid", "title": string | null, // best-effort extracted title "size_bytes": number, "modified_at": string // ISO 8601 timestamp } ] }

Pagination is explicit: omitting offset/limit returns every match with has_more=false. Nothing is ever silently dropped — has_more tells the caller when to request the next page with offset=<offset+count>.

Examples:

  • Use when: "What diagrams exist for this project?" -> type_filter="all"

  • Use when: "Show me all the Mermaid diagrams" -> type_filter="mermaid"

  • Use when: "List diagrams ten at a time" -> limit=10, then offset=10 for the next page

  • Don't use when: You already know the exact path and just need its content (use diagrams_get instead)

Error Handling:

  • Returns an empty "diagrams" array if the diagrams directory doesn't exist yet or is empty (this is not an error)

  • Returns an empty page (count 0, has_more=false) when offset is past the end of the matches

  • Returns "Error: Invalid pagination: ..." if offset is negative/non-integer or limit is outside 1-500

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

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of diagrams to return (1-500). Omit to return every remaining match.
offsetNoZero-based number of matching diagrams to skip before the returned page (default: 0).
type_filterNoRestrict results to a single diagram type, or 'all' for both.all

TDQS

A4.9/5.0
Behavior5/5

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

The annotations already indicate readOnly, idempotent, and non-destructive behavior, and the description adds substantial context: recursive scanning, no create/modify/render side effects, explicit pagination semantics, empty-directory behavior, out-of-range offset behavior, and error message shapes. There is no contradiction with the annotations.

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

Conciseness5/5

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

The description is long but well-structured and front-loaded with the core purpose. Every section (args, return schema, pagination, examples, error handling) earns its place since there is no output schema or separate documentation to carry that 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?

With no output schema, the description fully specifies the return JSON structure, pagination flags, field meanings, and error behavior. It also covers the main sibling-tool distinction and edge cases like empty directories and invalid offsets, making it complete for an agent to invoke correctly.

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?

The input schema has 100% description coverage, so the baseline is 3. The description adds value beyond the schema by explaining the pagination contract (has_more, offset=offset+count, nothing silently dropped) and giving concrete examples for using limit and offset together. It somewhat restates the schema defaults, which prevents a higher score.

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?

The description names a specific verb and resource: it scans the diagrams directory and lists PlantUML/Mermaid files. It also explicitly differentiates itself from siblings by stating it does NOT create, modify, or render diagrams, and by referring to diagrams_get when the exact path is already known.

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?

The description gives concrete 'Use when' examples for all filters and pagination scenarios, and a 'Don't use when' case naming diagrams_get as the alternative. This is explicit routing guidance that leaves no ambiguity about when to select this tool over siblings.

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

diagrams_list_templatesList Available Diagram TemplatesA
Read-onlyIdempotent

Discover the diagram templates diagrams_template can instantiate, without reading any template contents.

Lists the built-in skeleton kinds (each supports 'puml' and 'mermaid') plus the custom-template candidate names found as *.json entries directly under PROJECT_ROOT/.diagrams-templates. A candidate name is an identifier to pass as custom_template to diagrams_template with template='custom'; the definition, the selected dialect, and the emitted source are validated there, not here. Discovery reads directory entries only — file contents are never read, so a malformed JSON file can still appear as a candidate — and it never writes or creates a missing template directory.

The scan is bounded: at most 1000 directory entries are examined (MAX_TEMPLATE_SCAN_ENTRIES), counting non-template entries too, plus one lookahead to detect the cap. There is no pagination, no full directory total, and no global subset ordering promised when capped: custom_count describes only the returned candidates, and the returned names are sorted only within the capped subset, which depends on filesystem iteration order.

Args: (none): Call with {} — discovery takes no arguments.

Returns: JSON with schema: { "built_in": [ // one entry per built-in kind, in documented order { "template": "class" | "sequence" | "c4_context", "formats": ["puml", "mermaid"] } ], "custom": [ // candidate names, sorted within the scanned subset { "template": "custom", "custom_template": string, "relative_path": string } ], "custom_count": number, // length of "custom": returned candidates only, not a full total when capped "entries_scanned": number, // directory entries examined, including non-template entries "scan_limit": number, // 1000 "truncated": boolean, // true when the entry cap was reached "scan_warning": string | null,// human-readable warning when truncated, otherwise null "written": false // always false; discovery never writes }

Each custom relative_path identifies the project-relative file '.diagrams-templates/.json'. Pass the custom_template identifier, not this path, to diagrams_template.

Examples:

  • Use when: "What templates are available?" -> call with {}

  • Use when: "Do we have a team skeleton?" -> call with {}, then look for its name in "custom"

  • Use when: "Which built-in starter should I use?" -> call with {}, then pass one of the built_in names to diagrams_template

  • Don't use when: You want the skeleton source itself (use diagrams_template with a name from this listing)

  • Don't use when: You want generated content from code (use diagrams_generate or diagrams_generate_sequence)

Error Handling:

  • Unknown argument fields are rejected: discovery accepts only {}

  • A missing .diagrams-templates directory is not an error: "custom" is empty with truncated=false and scan_warning=null

  • Subdirectories, symlink files/directories, invalid identifiers, and extensions other than .json are excluded, not errors

  • A .diagrams-templates path that is not a regular directory is rejected without exposing absolute paths

  • Expected filesystem access failures return CustomTemplateError without absolute paths

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

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already establish read-only, idempotent, non-destructive, closed-world behavior, and the description adds substantial context beyond them: the bounded 1000-entry scan, absence of pagination or global ordering, the fact that malformed JSON still surfaces as a candidate, that the directory is never created, and that paths are never exposed in errors. This is far richer than the annotations.

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 before details, and each section is labeled (Args, Returns, Examples, Error Handling). It is longer than average, but the length is largely justified because no output schema exists and the return shape must be documented inline; the density is high but not padded.

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?

With no output schema, the description carries the full burden of describing the return payload and does so completely, including field-by-field semantics (custom_count vs entries_scanned, truncated, scan_warning, written). Error behavior and edge cases (missing directory, non-directory path, symlinks) are covered, so an agent needs nothing else.

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?

Zero parameters, so the baseline is 4. The description reinforces this with 'Call with {}' and notes that unknown argument fields are rejected, which is a small value-add over the empty schema with additionalProperties:false.

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 ('Discover the diagram templates diagrams_template can instantiate') and immediately distinguishes itself from the instantiating sibling by noting it reads no template contents. An agent can tell it apart from diagrams_template, diagrams_generate and diagrams_scaffold 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.

Usage Guidelines5/5

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

Provides explicit 'Use when' scenarios and, more importantly, 'Don't use when' exclusions that route to alternatives (diagrams_template for source, diagrams_generate/diagrams_generate_sequence for generated content). When-to-use and when-not-to-use are both spelled out.

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

diagrams_renderRender Diagram to ImageA
Read-onlyIdempotent

Render a PlantUML or Mermaid diagram to an image (SVG or PNG) and return it as base64-encoded image content.

Rendering requirements:

  • Mermaid: requires the 'mmdc' CLI (install with: npm install -g @mermaid-js/mermaid-cli). No fallback exists.

  • PlantUML: uses a local 'plantuml' CLI if installed. Without one, rendering fails unless remote rendering is explicitly enabled with ALLOW_REMOTE_PLANTUML=true, in which case it falls back to the configured PlantUML rendering server over HTTPS (requires internet access; sends diagram source to that server). DISABLE_REMOTE_PLANTUML=true always disables the fallback, even when the allow flag is set.

Args:

  • relative_path (string): Path to the diagram, relative to the diagrams root

  • format ('svg' | 'png'): Output image format (default: 'svg')

Returns: An image content block (base64-encoded), plus a JSON summary: { "relative_path": string, "format": "svg" | "png", "rendered": true }

Examples:

  • Use when: "Show me what the order-flow diagram looks like" -> relative_path="system/order-flow.puml", format="svg"

  • Don't use when: You just need the raw source text (use diagrams_get instead, it's much cheaper)

Error Handling:

  • Returns "Error: Local renderer image exceeded the 5000000-byte limit..." for oversized local SVG or PNG output; simplify or split the diagram

  • Returns "Error: No diagram found at ''" if the file doesn't exist

  • Returns "Error: Mermaid rendering requires the 'mmdc' CLI..." if rendering a Mermaid diagram without mmdc installed

  • Returns "Error: PlantUML rendering requires a local 'plantuml' CLI..." when no local CLI is installed and remote rendering is not explicitly enabled (set ALLOW_REMOTE_PLANTUML=true to opt in)

  • Returns "Error: PlantUML rendering server responded with ..." if both local and remote PlantUML rendering fail

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

ParametersJSON Schema
NameRequiredDescriptionDefault
formatNoOutput image format (default: 'svg').svg
relative_pathYesPath to the diagram to render, relative to the diagrams root.

TDQS

A4.7/5.0
Behavior5/5

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

Annotations declare readOnly/idempotent/openWorld, but the description adds critical behavior they cannot: per-format CLI prerequisites (mmdc, plantuml), the remote-rendering fallback that sends diagram source over HTTPS, the env flags governing it, a 5MB output limit, and the exact user-facing error strings. That is substantial operational context beyond structured fields.

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

Conciseness5/5

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

Clearly sectioned (requirements, args, returns, examples, error handling) and front-loaded with the one-line purpose. Given the tool's environment-dependent complexity, every section earns its place and nothing is padded.

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?

With no output schema, the description still specifies the return value (base64 image block plus JSON summary) and enumerates the failure modes an agent should anticipate. For a tool with external CLI and network dependencies, this is complete enough to call correctly.

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

Parameters3/5

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

Schema description coverage is 100% and both parameters are already documented in the schema (including the default and enum), so the description adds little semantic detail. The args and example mainly restate what the schema provides, making the baseline 3 appropriate.

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 (Render), the resource (PlantUML/Mermaid diagram), the output format (SVG/PNG), and the return shape (base64 image content). It is immediately distinguishable from siblings like diagrams_get, which the description explicitly contrasts.

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 an explicit 'Use when' example mapping a natural-language request to concrete args, plus a 'Don't use when' rule routing to diagrams_get with a cost rationale ('much cheaper'). When/when-not/alternative are all covered.

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

diagrams_save_exportSave Diagram Export as HTML FileA

Save a stored PlantUML or Mermaid diagram as one self-contained HTML file inside the diagrams root. The SVG is encoded as a data image, so renderer markup is not parsed into the HTML DOM. SVG image processing disables scripts and external resource loading. A restrictive content security policy allows only data images and inline wrapper styles. SVG text is not selectable in the exported image. Diagram source is escaped in a native collapsible block when include_source is set, and the artifact works offline without new dependencies.

Rendering uses the same path and the same rules as diagrams_render: Mermaid requires the local 'mmdc' CLI with no fallback, and PlantUML prefers a local 'plantuml' CLI, falling back to the configured remote server only when ALLOW_REMOTE_PLANTUML=true and DISABLE_REMOTE_PLANTUML is not 'true'. Remote PlantUML rendering sends diagram source to that server over HTTPS.

The finished bundle is measured before the output directories or file are created. A bundle larger than 5000000 bytes is refused. The target must end in .html (case-insensitive) and must not exist: existing files are refused atomically, never overwritten. Saved HTML files are excluded from diagram listing and CRUD tools. To replace an export, choose a different output_path or remove the existing target yourself.

Args:

  • relative_path (string, required): Path to the diagram, relative to the diagrams root

  • output_path (string, required): Path for the saved HTML file, relative to the diagrams root, ending in .html

  • include_source (boolean, default true): Embed the diagram source in a collapsible block

Returns: A short acknowledgement as a text content block (not the HTML itself), plus a JSON summary: { "relative_path": string, // POSIX form of the source diagram "output_path": string, // POSIX form of the saved HTML file "diagram_type": "plantuml" | "mermaid", "format": "html", "bytes": number, // UTF-8 byte length of the saved HTML "svg_chars": number, // image source characters after XML preamble stripping, before base64 encoding "source_included": boolean, // whether the source block was embedded "truncated": false, // always false; over-cap is an error, never a cut file "rendered_with": "local-plantuml" | "remote-plantuml" | "mmdc" }

Examples:

  • Use when: "Save the order-flow diagram as HTML inside the repo" -> relative_path="system/order-flow.puml", output_path="exports/order-flow.html"

  • Use when: "Save a standalone HTML of the checkout sequence without source" -> relative_path="system/checkout.mmd", output_path="exports/checkout.html", include_source=false

  • Don't use when: You want the HTML text back without writing a file (use diagrams_export, which returns the bundle and writes nothing)

  • Don't use when: You want the image alone (use diagrams_render, which returns an image block)

Error Handling:

  • Returns "Error: Local renderer image exceeded the 5000000-byte limit..." for oversized local SVG output before HTML bundling or persistence

  • Returns "Error: No diagram found at ''" if the diagram does not exist, before any render is attempted

  • Returns "Error: Mermaid rendering requires the 'mmdc' CLI..." when rendering a Mermaid diagram without mmdc installed (no fallback exists)

  • Returns "Error: PlantUML rendering requires a local 'plantuml' CLI..." when no local CLI is installed and remote rendering is not explicitly enabled (set ALLOW_REMOTE_PLANTUML=true to opt in)

  • Returns "Error: PlantUML rendering server responded with ..." when the opt-in remote fallback answers non-2xx

  • Returns "Error: The export bundle for '' is bytes, larger than the 5000000-byte limit, so it was not saved..." when the finished bundle exceeds the cap, with nothing written

  • Returns "Error: HTML export '' already exists..." if the output file already exists; choose another output_path or remove the target yourself

  • Returns "Error: '' does not have the .html export extension..." if output_path does not end in .html

  • Returns "Error: Refused to access path outside the diagrams root" if relative_path or output_path attempts to escape the diagrams directory

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

ParametersJSON Schema
NameRequiredDescriptionDefault
output_pathYesPath for the saved HTML file, relative to the diagrams root, ending in .html (case-insensitive). Intermediate directories are created. Existing files are refused, never overwritten.
relative_pathYesPath to the diagram to export, relative to the diagrams root.
include_sourceNoEmbed the diagram source in a collapsible block so the artifact explains itself (default: true). The block is a native <details> element, so it works without JavaScript.

TDQS

A4.8/5.0
Behavior5/5

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

Annotations declare a non-readonly, non-idempotent, non-destructive, open-world write; the description goes well beyond them, disclosing the atomic never-overwrite refusal, the 5,000,000-byte cap checked before any file is created, the CSP/script/external-resource restrictions, the mmdc-with-no-fallback requirement, and the HTTPS remote-PlantUML opt-in. This is exactly the extra context the annotations cannot carry, and nothing contradicts them.

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 the core purpose, then rendering rules, then caps and overwrite semantics; every section is purposeful. It is long, and the Args/Error Handling sections partly duplicate the prose above, but the density is justified by the number of distinct failure modes an agent must anticipate.

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?

Despite having no output schema, the description documents the return shape fully (text acknowledgement plus a JSON summary with bytes, svg_chars, source_included, truncated, rendered_with), enumerates ten distinct error strings, and covers path-escape refusal. Nothing an agent needs to invoke or recover from this tool 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, and the description does add meaning: output_path must not exist and is refused atomically, the .html check is case-insensitive, and include_source's collapsible block is described as a native <details> element that works without JavaScript. The Args block largely restates the schema, which caps this below a 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 ('Save a stored PlantUML or Mermaid diagram as one self-contained HTML file inside the diagrams root') and immediately distinguishes itself from diagrams_export and diagrams_render via explicit 'Don't use when' routing. An agent can pick it out of a 14-sibling set 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.

Usage Guidelines5/5

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

Both positive examples ('Save the order-flow diagram as HTML inside the repo') and negative cases are given, with the alternative named and the selecting condition stated: diagrams_export returns the bundle without writing, diagrams_render returns the image alone. No inference required.

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

diagrams_scaffoldScaffold TypeScript Classes from a DiagramA
Read-onlyIdempotent

Draft empty exported TypeScript classes from the entity-name candidates in a stored PlantUML or Mermaid diagram, returning source text to review and then save yourself.

This reads heuristic entity-name candidates through the existing extractor unchanged, so candidates may include aliases, namespaces, components, participants, and call names such as charge. By default (all opt-in flags false) it does NOT recover class kinds, members, field types, relations, or runtime behavior. Every result says so with confidence "heuristic" plus a heuristic_warning; review the draft before saving it as TypeScript yourself.

With include_members=true, simple top-level multiline class NAME { blocks can add member stubs. Names must be bare ASCII identifiers; quoted, aliased, generic, nested, or decorated classes are outside this subset. The first substantive line must be @startuml (PlantUML) or classDiagram (Mermaid).

Supported members: optional +, -, #, or ~ visibility; fields name: Type, Type name, or bare name; methods name(args) with an optional single-token return label, or PlantUML Type name(args). Without include_types, fields become unknown; methods accept ..._args: unknown[], return unknown, and throw the literal "Not implemented". Argument names, types, modifiers, and bodies are not recovered. Member names use the same ASCII identifier grammar and length cap as class names; constructor and prototype are excluded. Duplicate names keep their first occurrence across field/method collisions and repeated class blocks.

Unsupported syntax is skipped, including constructors, initializers, implementation bodies, and external Class : member notation. Whole-line comments, PlantUML block comments, and note bodies are ignored. Each emitted class receives at most 30 members; members_capped reports an additional recognized unique name beyond that limit. This is a heuristic subset, not a full parser.

With include_types=true (which implies include_members=true), accepted field labels resolve to a strict case-sensitive subset only: string, number, boolean, bigint, or exactly an emitted class name, optionally with one [] suffix, optionally paired with exactly one null arm in either order (for example, string | null or null | User[]); nullable labels canonicalize to Atom | null. Whitespace around arms and the separator is allowed, but not inside an atom. Bare null, undefined as a type atom, any, unknown, void, extra or duplicate arms, parentheses, other generics, objects, functions, qualified names, and nested arrays are unsupported. Classes past max_entities, skipped candidates, and nonexistent classes fall back to unknown. Accepted fields emit as name!: Type (definite assignment for strict TypeScript); every other emitted field keeps the member-mode name: unknown;. Methods stay literal throwing stubs with no recovered params or returns. Class references are heuristic labels only, with no supplied runtime value or relations claimed. typed_fields counts accepted emitted fields and unresolved_fields counts emitted fields falling back to unknown (never methods or skipped/over-cap members).

Array and ReadonlyArray accept exactly one supported primitive or emitted-class base and emit T[] or readonly T[] respectively. Either wrapper may have one null arm. No whitespace is allowed inside wrappers and nested wrappers or array arguments or array suffixes on wrappers remain unsupported. Wrapper and nullable labels require name: Type field notation. Trimmed labels are retained up to 82 characters including whitespace around the separator. Type identifiers remain limited to 60 characters. An overlong label falls back to unknown even if removing extra whitespace would make it fit.

With include_relations=true, typed members are enabled even if include_types/include_members are false. Body field labels use the same nullable grammar as include_types. Top-level Owner --> Target : role links become role!: Target;. Optional target multiplicity before Target (quoted , 0.., or 1..*) becomes role!: Target[];. Both endpoints must be selected emitted classes and independently declared plain top-level class NAME, class NAME { multiline blocks, or class NAME {} empty blocks. No endpoint classes are invented. Alias/quoted/generic/nested/implicit declarations and other arrows, multiplicities or free-text/unlabeled links are outside this subset.

Role names use the member identifier rules. Body fields/methods win collisions regardless of edge position, then the first accepted role wins. Relation fields follow body members. Comments, note bodies and nested blocks are ignored. At most 300 relationship fields are appended, within the existing class member cap. Recognized arrow lines not added (missing endpoints, invalid role, conflicts, duplicates or limits) increment relations_skipped. Unsupported grammar does not count. A novel candidate refused by either cap sets relations_capped; a class cap also sets members_capped. These are heuristic proposed fields, not recovered ownership, inheritance, runtime values or enforced cardinality.

Relation mode additionally returns include_relations:true, relations_included, relations_skipped, relations_capped, relation_limit. Type/member counts include appended fields. False or omitted include_relations preserves the three existing source and response modes.

It never writes, renders, fetches, or executes: one traversal-protected store read, pure filtering and emission, no new dependencies. Nothing lands outside the response until you save it with an explicit write. Still read-only with include_members=true or include_types=true.

Args:

  • relative_path (string, required): Path to the diagram, relative to the diagrams root

  • max_entities (integer 1-60, default 30): Hard cap on emitted classes

  • include_members (boolean, default false): Opt-in heuristic member stubs plus members metadata

  • include_types (boolean, default false): Opt-in heuristic field types; true implies include_members=true plus typed metadata

  • include_relations (boolean, default false): Named-arrow fields; implies include_types and include_members

Returns: JSON with schema: { "relative_path": string, // POSIX form "language": "typescript", "source": string, // the scaffold; identical to the text block ("" when no emittable names) "entities": string[], // emitted class names in candidate order, capped "entities_included": number, // length of "entities" "entities_available": number, // valid candidates before the cap "entities_capped": boolean, // true when valid names were dropped by the cap "entity_limit": number, // the applied cap (max_entities, at most 60) "skipped_entities": string[], // invalid or reserved candidates, independent of the cap "skipped_count": number, // length of "skipped_entities" "confidence": "heuristic", "heuristic_warning": string, // candidate-only limitations by default; member-mode limitations when include_members=true; typed-mode limitations when include_types=true "written": false, // always false; save the source yourself // include_members=true only: // "include_members": true, // "members_included": number, // total emitted field+method stubs across emitted classes // "members_capped": boolean, // true when a 31st unique supported member was found // "member_limit": 30 // fixed per-class member cap // include_types=true only (implies the member keys above): // "include_types": true, // "typed_fields": number, // emitted fields with an accepted type label (name!: Type) // "unresolved_fields": number // emitted fields falling back to name: unknown }

Names are emitted only when they match /^[A-Za-z_][A-Za-z0-9_]*$/ at most 60 characters and avoid reserved and TypeScript-forbidden class names. Other candidates are listed in skipped_entities without further renaming. An empty candidate set returns empty source.

Examples:

  • Use when: "Draft class shells for the names in this diagram" -> relative_path="models/order.puml"

  • Use when: "Give me TypeScript stubs for the Mermaid model" -> relative_path="models/order.mmd", max_entities=10

  • Use when: "Draft shells with heuristic member stubs" -> relative_path="models/order.puml", include_members=true

  • Use when: "Draft stubs with heuristic field types" -> relative_path="models/order.puml", include_types=true

  • Use when: "Draft fields from named arrows between my declared classes" -> relative_path="models/order.mmd", include_relations=true

  • Don't use when: You want full members, types, or relations (out of scope; default emits empty classes only, opt-in emits heuristic unknown-typed throwing stubs only, typed opt-in emits only the strict scalar/emitted-class subset with optional null and unknown fallback)

  • Don't use when: You want a diagram from code (use diagrams_generate)

Error Handling:

  • Returns "Error: No diagram found at ''" if the diagram does not exist, before any extraction

  • Returns "Error: Refused to access path outside the diagrams root" if relative_path attempts to escape the diagrams directory

  • Returns "Error: ... does not have a recognized diagram extension ..." when the path has no diagram extension

  • Returns "Error: Diagram source is bytes, larger than the 1000000-byte limit ..." when the stored source exceeds the byte cap; nothing partial is returned

  • An empty candidate set is not an error: source is "" with entities [] and the heuristic warning still explains the limitation

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

ParametersJSON Schema
NameRequiredDescriptionDefault
max_entitiesNoHard cap on emitted TypeScript classes, an integer between 1 and 60 (default: 30). The applied cap is reported as entity_limit; anything past it is counted in entities_available and flagged by entities_capped.
include_typesNoOpt-in heuristic field types for member stubs (default: false). True implies include_members=true; with relations disabled, false adds no new keys. True resolves field labels to string, number, boolean, bigint, or exactly an emitted class name, optionally with one [] suffix; a field may also have exactly one null arm in either order (canonicalized as Atom | null). Array<T> and ReadonlyArray<T> also accept a supported primitive or emitted-class base and emit T[] or readonly T[]. Whitespace around arms and the separator is allowed, not inside an atom. Accepted fields emit as name!: Type; all others emit as name: unknown.
relative_pathYesPath to the diagram to scaffold from, relative to the diagrams root.
include_membersNoOpt-in heuristic member stubs from plain class NAME { ... } blocks only (default: false). With other opt-ins disabled, false keeps empty classes with no new keys; true adds throwing stubs plus members metadata.
include_relationsNoOpt-in named association fields (default: false). Implies include_types and include_members. Only labeled --> relations between explicitly declared, emitted plain classes are used; no inheritance or runtime values.

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, but the description adds substantial context beyond them: it never writes, renders, fetches, or executes; there is one traversal-protected store read; confidence is always heuristic with a heuristic_warning; explicit per-mode caps (30 members/class, 300 relation fields, 60 entities, 1,000,000-byte limit) are disclosed. This is well beyond the annotation baseline.

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

Conciseness3/5

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

The purpose is front-loaded and the text is organized by mode, but the description is exhaustively long and repeatedly re-explains grammar subsets, limits, and return keys that are also captured in the schema and inputs. Many sentences carry real information, yet the volume is disproportionate and would benefit from tighter prose.

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?

With no output schema, the description carries the full return-value burden and does so thoroughly, documenting every response key per mode, the empty-candidate case, counted/flagged caps, and a detailed error taxonomy with exact messages. Nothing an agent needs to invoke and interpret the tool 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 description coverage is 100%, so the baseline is 3, and the verbose flag descriptions largely restate the schema. However, the description adds genuine meaning via the implication chain (include_relations implies include_types imply include_members) and the interaction rules (relations force typed members even when flags are false), which helps the agent reason about combined flag settings.

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?

The first sentence gives a specific verb and resource: drafting empty exported TypeScript classes from entity-name candidates in a stored PlantUML or Mermaid diagram. It clearly distinguishes itself from the reverse-direction sibling diagrams_generate. An agent can identify the tool's output shape (source text to review and save) without opening the 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?

The description supplies concrete 'Use when' scenarios for each opt-in flag and explicit 'Don't use when' exclusions, including naming diagrams_generate for the inverse workflow. It also states the default behavior (empty classes only) versus each opt-in tier, so the agent can pick the right mode directly.

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

diagrams_templateInstantiate a Diagram SkeletonA
Read-onlyIdempotent

Emit a built-in starter skeleton (class, sequence, or C4-context) or a custom project template in PlantUML or Mermaid, returning validated source text to fill in and then save with diagrams_create.

Built-in skeletons are pure and require no filesystem or code scan. Custom templates read one named JSON file under PROJECT_ROOT/.diagrams-templates; identical inputs and file contents yield identical source. No template evaluates code or fetches remote resources.

It never writes: nothing lands in the diagrams directory without an explicit diagrams_create call, and the emitted source clears the exact syntax gate that tool enforces, so the output can be saved as-is.

The three built-in kinds are 'class', 'sequence', and 'c4_context'. Use 'custom' with custom_template to load .json. The selected 'puml' or 'mermaid' object must contain 'source' and 'entity' strings. Source placeholders are {{title}} and {{entities}}; entity patterns support {{name}}. Reads are limited to 65536 bytes and expansion to 1000000 JavaScript string characters. Files must be regular files inside the template directory; symlinks, unknown fields, and unsupported placeholders are rejected.

Args:

  • template ('class' | 'sequence' | 'c4_context' | 'custom', required): Which starter skeleton to emit

  • custom_template (string, required only for custom): Identifier without path or extension, 1-64 letters, digits, underscores or hyphens

  • format ('puml' | 'mermaid', default 'puml'): Output dialect

  • title (string, optional, at most 200 chars): Diagram title; whitespace-only is rejected, never an empty title line

  • entities (string[], 1-20 items): Entity names, each an identifier matching /^[A-Za-z_][A-Za-z0-9_]*$/ at most 60 chars, no duplicates

Returns: JSON with schema: { "template": "class" | "sequence" | "c4_context" | "custom", "custom_template": string, // present only for custom templates "format": "puml" | "mermaid", "title": string | null, // the normalized one-line title, or null when none was given "source": string, // the skeleton; identical to the text block "entities": string[], // the names as accepted, in input order "entities_included": number, // length of "entities" "deterministic": true, // same inputs and template contents yield the same source "written": false // always false; save with diagrams_create }

Examples:

  • Use when: "Start a class diagram for the order model" -> template="class", entities=["User","Order"]

  • Use when: "Give me a Mermaid sequence skeleton for these services" -> template="sequence", format="mermaid", entities=["Checkout","Payment"]

  • Use when: "Sketch the C4 context for this system" -> template="c4_context", entities=["Web","Billing"]

  • Don't use when: You want generated content from code (use diagrams_generate or diagrams_generate_sequence)

  • Use when: "Use our team skeleton" -> template="custom", custom_template="team-model", entities=["User"]

Error Handling:

  • Input validation rejects unknown kinds/formats/keys, invalid custom identifiers, over-limit or whitespace-only titles, and invalid/duplicate/over-limit entity names

  • CustomTemplateError messages explain missing custom_template, invalid built-in/custom combinations, unreadable or invalid JSON files, unsupported dialects/placeholders, and read/expansion limits without exposing absolute paths

  • Emitted source passes the same syntax gate diagrams_create enforces; invalid template output returns a diagram validation error

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

ParametersJSON Schema
NameRequiredDescriptionDefault
titleNoOptional diagram title, at most 200 characters. Whitespace-only is rejected rather than emitting an empty title line. Internal whitespace runs are collapsed so the title stays one line, and the normalized value is what the source and the structured output report.
formatNoOutput dialect for the skeleton (default: 'puml').puml
entitiesYesEntity names to instantiate, 1 to 20 of them, each an identifier matching /^[A-Za-z_][A-Za-z0-9_]*$/ at most 60 characters long, with no duplicates. Names are emitted in the given order, one declaration each.
templateYesWhich starter skeleton to emit: 'class' (a box per entity), 'sequence' (a participant per entity), 'c4_context' (one context-level system per entity), or 'custom' (a named JSON template in the project's .diagrams-templates directory).
custom_templateNoCustom template identifier without extension or path; required only when template is 'custom'.

TDQS

A4.8/5.0
Behavior5/5

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

Beyond the readOnly/idempotent/non-destructive annotations, the description discloses determinism, that built-in kinds perform no filesystem or code scan, that custom templates read exactly one JSON file under PROJECT_ROOT/.diagrams-templates, hard read/expansion limits (65536 bytes, 1,000,000 characters), symlink/unknown-field/unsupported-placeholder rejection, and the guarantee that it never writes. It also states the emitted source clears the same syntax gate diagrams_create enforces, and describes the generic-error fallback.

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?

Purpose, purity guarantees, and the never-writes contract are front-loaded, and the Examples plus Error Handling sections are well-structured and earn their space. The verbatim Args restatement is redundant at 100% schema coverage, and the Returns block partially repeats the 'written: false; save with diagrams_create' point made earlier, so it is slightly longer than necessary.

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?

Since no output schema is declared, the explicit Returns JSON with field-by-field comments is exactly the missing piece and is supplied. Error taxonomy, limits, and the save-via-diagrams_create handoff are all covered, leaving no meaningful gap for an agent to call this tool correctly.

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 description coverage is 100%, so the baseline is 3; the description goes beyond it by documenting template-placeholder semantics ({{title}}, {{entities}}, entity-level {{name}}), the conditional nature of custom_template, and the cross-field rule that the selected dialect object must contain 'source' and 'entity' strings. The Args block largely restates the schema, so it does not lift this to a 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?

The first sentence gives a specific verb (emit) and resource (built-in starter skeleton or custom template) plus the output form (validated PlantUML/Mermaid source). It explicitly distinguishes itself from siblings by naming diagrams_create as the follow-up write step and diagrams_generate / diagrams_generate_sequence as the code-derived alternatives.

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?

Usage is spelled out both in prose ('Built-in skeletons are pure and require no filesystem or code scan') and in a Use when / Don't use when example list that maps concrete intents to parameter combinations. The 'Don't use when you want generated content from code' line routes the agent to the correct sibling without inference.

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

diagrams_updateUpdate Existing DiagramA
DestructiveIdempotent

Replace the full content of an existing PlantUML or Mermaid diagram file.

This performs a full-content replace, not a partial edit — pass the complete new diagram source. To create a new diagram, use diagrams_create (or set create_if_missing=true here).

Performs a basic, dependency-free syntax check before writing (not full validation): PlantUML must include @startuml/@enduml boundaries; Mermaid must start with a known diagram declaration. Clearly invalid or empty sources are rejected without overwriting the existing file.

Args:

  • relative_path (string): Path to the diagram, relative to the diagrams root

  • content (string): Full new diagram source text

  • create_if_missing (boolean): Create the file instead of erroring if it doesn't exist (default: false)

Returns: JSON with schema: { "relative_path": string, "updated": true }

Examples:

  • Use when: "Add a new field to the User class diagram" -> read current content with diagrams_get first, then call diagrams_update with the modified full content

  • Don't use when: The file doesn't exist yet and you don't want auto-creation (use diagrams_create)

Error Handling:

  • Returns "Error: No diagram found at ''" if the file doesn't exist and create_if_missing is false

  • Returns "Error: ... does not have a recognized diagram extension" if the extension isn't recognized

  • Returns "Error: Invalid PlantUML diagram (basic check): ..." if PlantUML source is empty or missing @startuml/@enduml boundaries (original file left unchanged)

  • Returns "Error: Invalid Mermaid diagram (basic check): ..." if Mermaid source is empty or has no recognized diagram declaration (original file left unchanged)

  • Returns "Error: Refused to access path outside the diagrams root" if relative_path attempts to escape the diagrams directory

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

ParametersJSON Schema
NameRequiredDescriptionDefault
contentYesNew full PlantUML or Mermaid source text that replaces the existing content.
relative_pathYesPath to the existing diagram, relative to the diagrams root.
create_if_missingNoIf true and no diagram exists at relative_path, create it instead of failing (default: false).

TDQS

A4.7/5.0
Behavior5/5

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

The description adds substantial behavior beyond the annotations: it discloses the pre-write syntax check, clarifies it is not full validation, states rejection conditions, and assures the original file is left unchanged on invalid input. This complements destructiveHint=true and idempotentHint=true without contradicting them.

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

Conciseness5/5

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

The description is long but well-structured with labeled sections, and the core behavior is front-loaded in the first paragraph. Every sentence serves a purpose, including the detailed error-handling list, which is practically useful for agents.

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?

For a mutation tool with no output schema, the description is complete: it specifies the return shape, error cases, validation behavior, file-overwrite semantics, and sibling alternatives. An agent has enough information to invoke the tool correctly and anticipate failures.

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

Parameters3/5

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

Schema description coverage is 100%, so the baseline is 3 even though the description mostly restates the parameter meanings. It does add mild context (e.g., 'pass the complete new diagram source' and create_if_missing behavior), but it does not uncover anything fundamentally beyond the schema.

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?

The description states a specific verb ('Replace') and resource ('existing PlantUML or Mermaid diagram file'), and explicitly clarifies it is a full-content replace rather than a partial edit. It differentiates itself from diagrams_create by naming the sibling tool and the create_if_missing alternative.

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?

Usage guidance is explicit: it says when to use this tool, when not to, and names alternatives. The 'Use when' and 'Don't use when' examples directly instruct agents to read current content with diagrams_get first and to prefer diagrams_create for new files unless auto-creation is desired.

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.

  1. 8 tool updatesv0.10.0
    • Addeddiagrams_diff
    • Addeddiagrams_export
    • Addeddiagrams_generate
    • Addeddiagrams_generate_sequence
    • Addeddiagrams_list_templates
    • Addeddiagrams_save_export
    • Addeddiagrams_scaffold
    • Addeddiagrams_template
  2. 7 tool updatesv0.1.0
    • First observeddiagrams_check_consistency
    • First observeddiagrams_create
    • First observeddiagrams_delete
    • First observeddiagrams_get
    • First observeddiagrams_list
    • First observeddiagrams_render
    • First observeddiagrams_update

TDQS

A4.7/5.0

Scored across 15 tools

Disambiguation4/5

Most tools target clearly distinct operations, and descriptions include explicit 'Don't use when' guidance that steers between near-pairs. The main soft spots are the export/save_export pair (return HTML vs write HTML) and the generation family (generate, generate_sequence, template, scaffold), which overlap conceptually but are differentiated by target artifact and source.

Naming Consistency5/5

Every tool uses a consistent snake_case verb_noun pattern under a uniform 'diagrams_' prefix (create, get, update, delete, list, render, export, diff, generate, etc.). Naming is fully predictable with no mixed conventions.

Tool Count5/5

15 tools sit at the top of the well-scoped range, but each covers a distinct capability (CRUD, render, export, diff, consistency, code-to-diagram generation, scaffolding, templates). No tool feels redundant or ceremonial for a rich diagram-management domain.

Completeness5/5

Full lifecycle coverage is present: list/get/create/update/delete for storage, plus render, export/save, diff, consistency checking, generation from code, and template discovery. The surface supports both authoring and review workflows with no obvious dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables generating cloud architecture diagrams, flowcharts, sequence diagrams, and more using three rendering engines: mingrammer/diagrams, Mermaid, and PlantUML.
    43 PyPI
    3
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables LLMs to draw interactive diagrams (architecture, sequence, class) inside the editor, with clickable nodes that jump to source code.
    9
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to create, read, update, and delete Draw.io diagrams, allowing automated generation of architectural diagrams, flowcharts, and visual documentation.
    27 npm
    MIT