Skip to main content
Glama

mcp-archimate

CI PyPI Python License: GPL v3

An MCP server that lets an AI agent build, validate and export real ArchiMate models — the kind that open in Archi and survive a round trip.

It exposes 45 tools, 9 resources and 4 guided prompts over stdio. The agent describes architecture; the server enforces what ArchiMate actually permits, lays out the diagrams, and writes the file.

"Model our order-to-cash flow, then export it so I can open it in Archi."

Why this exists

Asking a model to emit ArchiMate XML directly produces files that look plausible and fail to open. Relationship types are invented, ids do not resolve, diagrams have no coordinates.

This server closes that gap. It holds the model in memory, refuses invalid relationships with the valid alternatives attached, positions every node and routes every connection, and serialises through pyArchimate rather than string templating. It owns zero ArchiMate rules of its own — every validity verdict is delegated to pyArchimate's relationship matrix (ArchiMate 3.2-compatible), so it cannot drift into a private dialect.

The division of labour is deliberate: the server is a constraint engine, the agent is the architect. It will tell you a BusinessProcess cannot serve an ApplicationService and what can; it will not decide what your architecture should be.

Related MCP server: arcade-azure-devops-mcp

Install

Nothing to clone. With uv:

uvx mcp-archimate

That runs the server over stdio, which is what an MCP client wants. Running it in a terminal by hand will just sit there waiting for JSON-RPC — that is correct.

Alternatives:

pipx run mcp-archimate
pip install mcp-archimate

Requires Python 3.10 or newer.

Connect it to a client

Claude Code:

claude mcp add archimate -- uvx mcp-archimate

Claude Desktop — in claude_desktop_config.json:

{
  "mcpServers": {
    "archimate": {
      "command": "uvx",
      "args": ["mcp-archimate"]
    }
  }
}

Codex — in ~/.codex/config.toml:

[mcp_servers.archimate]
command = "uvx"
args = ["mcp-archimate"]

MCP Inspector:

npx @modelcontextprotocol/inspector uvx mcp-archimate

No API keys and no configuration file. The only environment variables it reads are the two optional filesystem roots described under Security considerations; unset, they default to your home directory.

Example prompts

You talk to your agent in plain language; it picks the tools. The tool names below are just what it will reach for, so you can follow along.

Everything here is copy-pasteable. Start with the first one.

Build something small

Create an ArchiMate model of a customer onboarding process. Cover the business
layer (the customer, the onboarding process, the identity check) and the
application layer (the onboarding portal and an identity verification service).
Connect them properly, put it in one view, lay it out, and export it so I can
open it in Archi.

Uses create_empty_model → add_element → add_relationship → create_view → auto_layout_view → export_model_to_file.

Explore a model you already have

Load ~/models/enterprise.archimate and tell me what's in it: how big it is,
what's in each layer, and whether anything is broken.

load_model_from_file loads and inspects in one call, so the agent gets counts, validation state and view summaries immediately.

Follow-ups worth asking:

Which elements aren't used in any view?
Show me everything that depends on the payment service.

Edit an existing model

The common case after the first build. Be specific about what to change and the agent will make a focused edit rather than rebuilding.

Add a "Fraud Screening" application service to the model, have it serve the
checkout process, and host it on the same node as the payment service. Then
re-lay-out the views it appears in.
Rename "Cust Mgmt Svc" to "Customer Management Service" everywhere, and give it
a proper description explaining what it does.
The order service and the inventory service are connected with a Serving
relationship, but it should be asynchronous. Change it to a Flow relationship
and tell me if that's actually valid ArchiMate.

That last one is worth trying — the server will tell you which relationship types are legal between those two element types, with alternatives, rather than silently accepting something Archi will reject.

Improve a model

Review this model for quality problems and fix the ones that are safely
fixable. Explain anything you can't fix automatically and why.

Uses build_quality_report → repair_semantic_issues. The server only auto-repairs deterministic cases; anything needing an architectural decision is reported back to you rather than guessed at.

Every view in this model is a wall of boxes. Add layer bands, lay everything
out again, and add notes explaining what each view is for.
Some of my relationships aren't shown in any view. Find them and add a coverage
view so nothing is hidden.

Validate and export

Check the model for problems, then export it to ~/Desktop/architecture.archimate
in Archi's native format with a strict quality gate so it won't write a broken
file.

quality_gate="strict" blocks the export on visual, semantic or coverage failures — useful when the file is going to someone else.

To look at a diagram without opening Archi:

Render the Application Cooperation view to an SVG on my Desktop.

A full build

A single prompt that exercises most of the server. Expect it to take a few minutes and make a lot of tool calls.

Create an ArchiMate model representing a realistic composite ecommerce
architecture (not tied to a real company). Use the archimate MCP tools. Scope:

- Business layer: Customer / Warehouse Staff / Support Rep actors with roles,
  core processes (browse, cart, checkout, payment, fulfillment, support),
  business services, and key business objects (order, customer account).
- Application layer: microservices — storefront web app, API gateway, and one
  component + service pair per capability (catalog, search, cart, checkout,
  payment, order management, inventory, shipping, notification, customer
  support), plus their data objects.
- Technology layer: cloud infrastructure — container orchestration, a database
  per service that needs one, a cache, a message broker for async events, a
  load balancer / CDN, and an external payment gateway node.
- Relationships: standard ArchiMate conventions (ApplicationService serves
  BusinessProcess, Component realizes Service, Node serves Component for
  hosting, Access for data reads/writes, Flow for async events). Validate with
  semantic_validation='strict' and fix any invalid combinations using the
  suggested repairs.
- Views: Business Process View, Application Cooperation View, Technology
  Deployment View, and a Layered Overview showing one cross-layer slice (the
  checkout journey end to end). Auto-layout each view with layer bands.
- Run ensure_all_relationships_in_views, build_quality_report and
  validate_model before exporting. Export with quality_gate='strict'.

Add descriptions and annotations throughout.

Skip the clarifying questions — go straight to building.

The last line matters. Without it a good agent will stop and ask you to narrow the scope, which is usually the right instinct but not what you want here.

A note for agents

Call get_usage_guide first. It returns the operating rules, common anti-patterns and recommended call sequences — it exists so an agent does not have to read this server's source code to work out how to use it.

What's in the box

Model (17 tools)

create, load, export, metadata, quality reports, TOGAF readiness

Views (12 tools)

create views, add nodes, auto-layout, layer bands, diagram notes, SVG rendering

Relationships (7 tools)

create, validate, compatibility lookup, intent-based recommendation, deterministic repair

Elements (4 tools)

add, update, delete, query

Workflow (3 tools)

usage guide, load-and-inspect, inspect active model

Queries (2 tools)

filtered search across the model

Resources (6 + 3 templates)

read-only views of the model under pyarchimate://activemodel/...; the three templated ones are returned by resources/templates/list

Prompts (4)

guided load → inspect → edit → validate → export workflows

Full parameter and response documentation is in the User Guide.

Two export formats — they are not interchangeable

output_format

Produces

In Archi

"archi"

Archi's native .archimate

Opens directly

"archimate" (default)

Open Group exchange XML

Must be imported

SVG is not a third format. render_view_to_svg_file writes a picture for a human to look at; it carries no model semantics and cannot be loaded back.

Layout

Diagrams are laid out, not just populated: nodes are placed in ArchiMate layer order with lane wrapping and barycenter alignment, multi-layer views get labelled layer bands, and connections are routed around obstacles rather than drawn as diagonals through boxes.

Security considerations

Two things are worth knowing before you point an agent at this server. The full picture, including how to report a vulnerability, is in SECURITY.md.

The file tools are confined to allowed roots. load_model_from_file reads, and export_model_to_file and render_view_to_svg_file write, only inside the directories named by MCP_ARCHIMATE_ALLOWED_READ_ROOTS and MCP_ARCHIMATE_ALLOWED_WRITE_ROOTS. Unset, both default to your home directory, which keeps the quickstarts above working while putting /etc, system locations and other users' files out of reach. Paths are fully resolved first, so .. and symlinks cannot escape. Set the variables to a dedicated models directory to narrow it further — with the home default, ~/.ssh is still readable. This is not a sandbox: the server runs as the account that launched it, and exports still overwrite without prompting inside an allowed root. It exists because the caller here is usually an LLM agent rather than a person typing a path, so treat a path argument the way you would treat a shell command an agent proposed. For a hard boundary, run the server in a container or under a dedicated account.

Model files are untrusted input. The loader rejects DTDs and entity declarations outright, parses with external entity resolution and network access disabled, caps content at 10 MB and allow-lists the root element — so XXE and entity-expansion attacks are blocked, and this is verified adversarially in tests/test_security.py rather than assumed. What it cannot block is prompt injection: element names, documentation and properties are attacker-controllable text that flows back to your agent. Treat model content as data, never as instructions.

The server makes no network requests, collects no telemetry, and needs no credentials of any kind.

Documentation

Document

For

User Guide

Everyone. Tool parameters, response schemas, workflows, troubleshooting

Technical Architecture

Contributors. Design, layers, pyArchimate usage patterns

Layout Improvement Plan

Layout work. Measurements and rejected approaches

Quality & Validation PRD

The validation tool suite and the constraint-engine split

CHANGELOG

What changed, newest first

CONTRIBUTING

Setup, branch model, how to propose changes

SECURITY

Trust model and vulnerability disclosure

Decision records

Architecture decision records — why things are the way they are

Development

git clone https://github.com/byrondelgado/mcp-archimate.git
cd mcp-archimate
uv sync --all-groups

uv run pytest
uv run ruff check
uv run mcp dev pyarchimate_mcp_server/server.py   # with MCP Inspector

See CONTRIBUTING.md for the branch model and conventions, and CLAUDE.md for the repository's operating contract — it documents several things that look like mistakes and are not.

Credits

This server is built on pyArchimate by Xavier Mayeur, which does the actual ArchiMate modelling work. Every model this server creates, reads, lays out, validates and exports passes through it. If this project is useful to you, pyArchimate is the reason.

License

GPL-3.0-or-later. See LICENSE for the full text and NOTICE for attribution.

This is inherited, not chosen. pyArchimate is GPL-3.0-only and is a required runtime dependency — the server cannot function without it — so the combined work you actually run is governed by the GPL. Releasing this server under permissive terms would misrepresent that.

What this means in practice:

  • Using the server does not put your models under the GPL. The .archimate and exchange files you produce are your own work, exactly as documents written in a GPL text editor are.

  • It does not reach the agent or client that calls it. An MCP server is a separate process communicating over stdio JSON-RPC. Copyleft attaches to distributing this program, not to software that talks to it across that boundary.

  • It does apply if you distribute a modified version of this server, or ship it inside something you distribute. Then the GPL's source-availability terms apply to that work.

This is a plain-language summary, not legal advice. Read the license, and take your own advice if the distinction matters to your situation.


ArchiMate is a registered trademark of The Open Group. This project is an independent implementation, not affiliated with or endorsed by The Open Group or the Archi project.

Available Tools

45 tools
add_connections_to_viewA

Add multiple visual connections to a view in one call.

Each connection item supports the same fields as
`add_connection_to_view`. Both short and long field names are
accepted (`relationship` or `relationship_id`, `id` or
`connection_id`).

Connection item shape:
    ```
    {
      "id": "id-uses-conn",          # optional stable ref
      "relationship": "id-uses"      # required (alias: relationship_id)
    }
    ```

Args:
    view_id: ID of the target view.
    connections: List of connection item objects.
    rollback_on_error: When true (default), restore the previous
        view state if any item fails.

Returns:
    Success envelope with `data.connection_ids`, `data.count`, and
    `data.rollback_on_error`.

Errors:
    `ModelOperationError` and `RelationshipNotFoundError` for the
    first failing item.

Inputs: view_id (required), connections (required), rollback_on_error. Returns: object

add_connection_to_viewA

Add a visual connection for a relationship in a view.

Both endpoint elements of the relationship must already be visible
as nodes in the view. Use `add_node_to_view` to add missing
endpoints first, or call `connect_visible_relationships` to draw
every relationship whose endpoints are already visible.

Args:
    view_id: ID of the target view.
    relationship_id: ID of the relationship to render.
    connection_id: Optional stable visual connection ID. When
        omitted a UUID is generated. Must be unique across the
        *entire* active model — not just within this call, this
        batch, or this concept type. An id already used by any
        element, relationship, view, node or connection is
        rejected. When generating ids across several batches,
        namespace them (`bp-`, `ac-`, `tech-`) so batches cannot
        collide.

Returns:
    Success envelope with `data.connection_id` containing the
    visual connection UUID.

Errors:
    `ModelOperationError` when `view_id` is unknown, when either
        endpoint node is not present in the view, or when
        `connection_id` is duplicated.
    `RelationshipNotFoundError` when `relationship_id` is unknown.

Inputs: view_id (required), relationship_id (required), connection_id. Returns: object

add_elementA

Add a new ArchiMate element to the active model.

Call `list_supported_types` to discover valid `element_type` values
if you are not certain. The response `data.id` is the canonical
element ID; use it as `source_id`/`target_id` when adding
relationships and as `element_id` when adding view nodes.

Args:
    element_type: A supported ArchiMate element type, e.g.
        `BusinessActor`, `BusinessProcess`, `ApplicationComponent`,
        `ApplicationService`, `DataObject`, `Node`, `Artifact`,
        `Goal`, `Stakeholder`, `Grouping`, `AndJunction`,
        `OrJunction`. Use `list_supported_types` for the full list.
    name: Element name. Must be a non-empty string.
    description: Optional element documentation text.
    folder_path: Optional conceptual folder path. Roots are
        normalized: `Business`, `/Business`, and `business` resolve
        to `/Business`. Sub-folders such as `/Business/Actors` are
        preserved.
    properties: Optional custom property key-value pairs. Values are
        stored as strings.
    element_id: Optional stable element ID. When omitted a UUID is
        generated. Must be unique across the
        *entire* active model — not just within this call, this
        batch, or this concept type. An id already used by any
        element, relationship, view, node or connection is
        rejected. When generating ids across several batches,
        namespace them (`bp-`, `ac-`, `tech-`) so batches cannot
        collide.

Returns:
    Success envelope with `data` shaped like an `ElementDetail`:
    `{id, name, type, description, properties, folder,
    incoming_relationship_ids, outgoing_relationship_ids}`.

Errors:
    `INVALID_ELEMENT_NAME` when `name` is missing or blank.
    `InvalidElementTypeError` for an unknown `element_type`.
    `ModelNotFoundError` if no model is active.
    `ModelOperationError` for a duplicate `element_id` or invalid
    folder path.

Inputs: name (required), element_type (required), element_id, properties, +2 more. Returns: object

add_elementsA

Add multiple elements to the active model in one call.

Each element item supports the same fields as `add_element`. Both
short and long field names are accepted (`type` or `element_type`,
`id` or `element_id`).

IDs are unique across the **entire active model**, not per call,
per batch, or per concept type. Splitting a build across several
batches does not give each batch its own id space, so namespace
generated ids (`bp-`, `ac-`, `tech-`) rather than restarting the
same naming pattern in each one.

Element item shape:
    ```
    {
      "id": "id-customer",        # optional stable ref
      "name": "Customer",          # required
      "type": "BusinessActor",     # required (alias: element_type)
      "description": "...",       # optional
      "folder_path": "/Business", # optional
      "properties": {"k": "v"}     # optional
    }
    ```

Args:
    elements: List of element item objects.
    rollback_on_error: When true (default), restore the previous
        model state if any item fails. Set to false to keep partial
        results.

Returns:
    Success envelope with `data.elements` (list of `ElementDetail`),
    `data.count`, and `data.rollback_on_error`.

Errors:
    `ModelNotFoundError`, `InvalidElementTypeError`,
    `ModelOperationError` for the first failing item.

Inputs: elements (required), rollback_on_error. Returns: object

add_nodes_to_viewA

Add multiple visual nodes to a view in one call.

Each node item supports the same fields as `add_node_to_view`. Both
short and long field names are accepted (`element` or `element_id`,
`id` or `node_id`).

Node item shape:
    ```
    {
      "id": "id-customer-node",   # optional stable ref
      "element": "id-customer",   # required (alias: element_id)
      "x": 40, "y": 40,            # optional, auto-placed if absent
      "width": 160, "height": 80   # optional, defaults shown
    }
    ```

Args:
    view_id: ID of the target view.
    nodes: List of node item objects.
    rollback_on_error: When true (default), restore the previous
        view state if any item fails.

Returns:
    Success envelope with `data.node_ids`, `data.count`, and
    `data.rollback_on_error`.

Errors:
    `ModelOperationError` (view not found / duplicate node_id) and
    `ElementNotFoundError` for the first failing item.

Inputs: nodes (required), view_id (required), rollback_on_error. Returns: object

add_node_to_viewA

Add an ArchiMate element as a visual node in a view.

If `x`/`y` are omitted, or the requested rectangle would overlap an
existing node, the server places the node in the next free slot.
Default node size is 160x80 (junctions are normalized to 32x32 by
`auto_layout_view`).

Args:
    view_id: ID of the target view.
    element_id: ID of the element to render in the view.
    x: Optional preferred X coordinate (top-left, integer pixels).
    y: Optional preferred Y coordinate (top-left, integer pixels).
    width: Node width in pixels. Defaults to 160.
    height: Node height in pixels. Defaults to 80.
    node_id: Optional stable visual node ID. When omitted a UUID is
        generated. Must be unique across the
        *entire* active model — not just within this call, this
        batch, or this concept type. An id already used by any
        element, relationship, view, node or connection is
        rejected. When generating ids across several batches,
        namespace them (`bp-`, `ac-`, `tech-`) so batches cannot
        collide.

Returns:
    Success envelope with `data.node_id` containing the visual
    node's UUID.

Errors:
    `ViewNotFoundError` (returned as `ModelOperationError` from the
        manager) when `view_id` is unknown.
    `ElementNotFoundError` when `element_id` is unknown.
    `ModelOperationError` for a duplicate `node_id`.

Inputs: view_id (required), element_id (required), x, y, +3 more. Returns: object

add_note_to_viewA

Add a diagram-only note (sticky annotation) to a view.

Use this to comment on a diagram — a caveat, an owner, a "retire in
FY27". Do NOT create a `Grouping` element just to write a comment:
that pollutes the model tree and participates in validation, while a
note does not.

Notes are visual only. A note has no ArchiMate element, no folder
and no model-tree entry, so it never shows up in `query_elements`,
`count_by_type`, `list_orphan_elements` or the coverage section of
`build_quality_report`. `connect_to_node_ids` draws annotation-only
connector lines that create NO ArchiMate relationship.

`x`/`y` are kept exactly as given, including across
`auto_layout_view` (both layout engines), because a note annotates
one specific spot. Layout will not move element nodes out from under
a note, so place notes in free space — off to the side of the
diagram, or below it. Routed connections are drawn around notes.

Args:
    view_id: ID of the target view.
    text: Note text. Must be non-empty; kept verbatim, so multi-line
        text keeps its line breaks and indentation. Verbatim also
        means escape sequences are NOT interpreted: pass real line
        breaks for a multi-line note, because a literal backslash-n
        is stored and rendered as those two characters.
    x: X coordinate (top-left, integer pixels). Used exactly.
    y: Y coordinate (top-left, integer pixels). Used exactly.
    width: Note width in pixels. Defaults to 185 (Archi's default).
    height: Note height in pixels. Defaults to 80.
    connect_to_node_ids: Optional list of things to point at. Each
        entry may be a visual node ID or an element ID that is
        already visible in this view.
    note_id: Optional stable visual node ID. When omitted a UUID is
        generated. Must be unique across the
        *entire* active model — not just within this call, this
        batch, or this concept type. An id already used by any
        element, relationship, view, node or connection is
        rejected. When generating ids across several batches,
        namespace them (`bp-`, `ac-`, `tech-`) so batches cannot
        collide.

Returns:
    Success envelope with `data.node_id`, `data.connection_ids`,
    `data.connected_node_ids` (resolved visual node IDs),
    `data.text`, and the geometry `data.x`, `data.y`,
    `data.width`, `data.height`.

Errors:
    `INVALID_NOTE_TEXT` when `text` is missing or blank.
    `ViewNotFoundError` when `view_id` is unknown.
    `ModelOperationError` for a duplicate `note_id`, or for connect
        targets that are not visible in the view — the unresolved
        IDs are listed in `error.details.unknown_ids` and nothing is
        created.

Notes are not updatable or deletable yet: recreate the view (or the
note) if the text or placement needs to change.

Inputs: x (required), y (required), text (required), view_id (required), +4 more. Returns: object

add_relationshipA

Add a new ArchiMate relationship between two elements.

Both endpoints must already exist as elements in the active model.
Use `list_supported_types` to discover valid `relationship_type`,
`access_type`, and `influence_strength` values.

Args:
    relationship_type: A supported pyArchimate relationship type,
        without the `Relationship` suffix. Examples: `Assignment`,
        `Serving`, `Composition`, `Aggregation`, `Realization`,
        `Triggering`, `Flow`, `Access`, `Influence`,
        `Specialization`, `Association`. Note: Archi's "Used By"
        concept maps to `Serving`.
    source_id: ID of the source element.
    target_id: ID of the target element.
    name: Optional relationship name.
    description: Optional documentation text.
    properties: Optional custom property key-value pairs (string
        values).
    access_type: Required only for `Access` relationships. One of
        `Access`, `Read`, `Write`, `ReadWrite`.
    influence_strength: Required only for `Influence` relationships.
        One of `+`, `++`, `-`, `--`, or `0`-`10`.
    relationship_id: Optional stable relationship ID. When omitted a
        UUID is generated. Must be unique across the
        *entire* active model — not just within this call, this
        batch, or this concept type. An id already used by any
        element, relationship, view, node or connection is
        rejected. When generating ids across several batches,
        namespace them (`bp-`, `ac-`, `tech-`) so batches cannot
        collide.

Returns:
    Success envelope with `data` shaped like a `RelationshipDetail`:
    `{id, name, type, description, properties, access_type,
    influence_strength, source_element_id, target_element_id}`.

Errors:
    `InvalidRelationshipTypeError` for an unknown
        `relationship_type`.
    `ElementNotFoundError` when `source_id` or `target_id` is
        unknown.
    `ModelNotFoundError` if no model is active.
    `ModelOperationError` for invalid relationship combinations,
        duplicate `relationship_id`, or unsupported access/influence
        values.

Inputs: source_id (required), target_id (required), relationship_type (required), name, +7 more. Returns: object

add_relationshipsA

Add multiple relationships to the active model in one call.

Each relationship item supports the same fields as `add_relationship`.
Short and long field names are both accepted (`type` or
`relationship_type`, `source` or `source_id`, `target` or
`target_id`, `id` or `relationship_id`).

IDs are unique across the **entire active model**, not per call,
per batch, or per concept type. Splitting a build across several
batches does not give each batch its own id space, so namespace
generated ids (`bp-`, `ac-`, `tech-`) rather than restarting the
same naming pattern in each one.

Relationship item shape:
    ```
    {
      "id": "id-uses",                # optional stable ref
      "type": "Serving",                # required (alias: relationship_type)
      "source": "id-customer",          # required (alias: source_id)
      "target": "id-portal",            # required (alias: target_id)
      "name": "uses",                   # optional
      "description": "...",            # optional
      "properties": {"k": "v"},         # optional
      "access_type": "Read",            # for Access only
      "influence_strength": "+"         # for Influence only
    }
    ```

Args:
    relationships: List of relationship item objects.
    rollback_on_error: When true (default), restore the previous
        model state if any item fails.

Returns:
    Success envelope with `data.relationships` (list of
    `RelationshipDetail`), `data.count`, and
    `data.rollback_on_error`.

Errors:
    `InvalidRelationshipTypeError`, `ElementNotFoundError`,
    `ModelNotFoundError`, `ModelOperationError` for the first
    failing item.

Inputs: relationships (required), rollback_on_error, semantic_validation. Returns: object

assess_togaf_readinessA
Read-only

Return advisory TOGAF-oriented readiness findings.

Advisory only. `data.compliance_claim` is always `false`: this is a
prompt for your own review, not a conformance result, and the
checklist is deliberately fixed.

Scoring: seven checks, one point lost per finding, so
`data.score` runs 0-7 against `data.max_score`. `data.status` is
`ready` when nothing fired, `partial` at a score of 3 or more, and
`limited` below that — so `limited` is the floor, and a model with
no Motivation or Strategy content scores 0 legitimately rather than
because something went wrong.

Returns:
    Success envelope with `data.status`, `data.score`,
    `data.max_score`, `data.advisory_findings` (each with `code`,
    `severity`, `message`), `data.advisory_findings_count`,
    `data.hard_failures`, `data.hard_failures_count`, and
    `data.compliance_claim`.

Errors:
    `ModelNotFoundError` if no model is active.

Inputs: include_hard_validation, include_quality_assurance_views. Returns: object

auto_layout_viewA
Idempotent

Automatically reposition all nodes in a view to avoid overlap.

The default `internal` layout nests Aggregation/Composition members
inside visible Grouping nodes, wraps wide lanes into multiple rows,
aligns connected nodes vertically across lanes, and routes
connections orthogonally around nodes. With `layer_bands` (default
true) and the `layered_by_type` strategy, views spanning two or
more ArchiMate layers get labeled visual bands (diagram-only Archi
Groups — the semantic model is never modified; set
`layer_bands=false` to disable).

The engine choice applies to this call only. It is never stored on
the model or the view, so it cannot appear in an export or in
Archi's Properties tab.

Note: parameter is `strategy` (matches `auto_layout_view`) but the
equivalent parameter on `export_model_content` and
`export_model_to_file` is named `layout_strategy`.

Args:
    view_id: ID of the view to lay out.
    strategy: One of:
        - `layered_by_type` (default): ArchiMate semantic lanes
          (Motivation/Strategy on top, then Business, Application,
          Application Data, Technology/Physical/Implementation).
        - `layered`: relationship-direction layered, source nodes
          before target nodes.
        - `grid`: compact non-overlapping grid, no semantic
          ordering.
        Ignored (but still validated) by the `pyarchimate` engine,
        which has a single fixed algorithm.
    layout_engine: One of:
        - `internal` (default): everything described above.
        - `pyarchimate`: pyArchimate's own coarse-grid placement.
          Much faster on large views, but it applies no `strategy`,
          no layer bands, no lane wrapping, no barycenter
          alignment, and no ArchiMate lane ordering (its own layer
          classification misplaces SystemSoftware, Artifact, Path,
          Equipment, Facility, Material, Contract, Representation
          and ImplementationEvent). Best for flat views of
          default-sized nodes. It has no collision detection, so a
          view whose nodes do not fit its grid cell is refused
          rather than silently overlapped — see Errors.

Returns:
    Success envelope with the laid-out view in `data`. Under
    `pyarchimate` the message says which options were not applied.

    `detail="summary"` (default) returns the view's identity,
    `properties`, `metadata`, `node_count`, `connection_count`, and
    a `bounds` box (`{x, y, width, height}`, or null for an empty
    view) giving the canvas the layout consumed — enough to place a
    note in free space afterwards.

    `detail="full"` adds `nodes` (each with x/y/width/height) and
    `connections`. Ask for it when you need per-node geometry; it
    is several thousand tokens on a mid-sized view.

    Both shapes report the band outcome directly:
    `layer_bands_created` (int) and `layer_bands_reason`, which is
    null when bands were created and otherwise one of
    `single_layer_view`, `coverage_view`, `not_requested`,
    `strategy_does_not_use_bands`, or
    `engine_does_not_support_bands`. Zero bands on a single-layer
    view is correct, not a failure.

Errors:
    `ViewNotFoundError` (returned as `ModelOperationError`) when
        `view_id` is unknown.
    `ModelOperationError` for an unknown strategy, engine, or
        `detail` level, with close matches in
        `error.details.suggestions`.
    `ModelOperationError` when `layout_engine="pyarchimate"` cannot
        lay the view out safely, with `error.details.grid_size` and
        `error.details.oversized_nodes`. No placement is written, so
        the view is never left half laid out, but the shared
        prologue (Grouping nesting, group sizing) may already have
        repaired it. Retry with `layout_engine="internal"`.

Inputs: view_id (required), detail, strategy, layer_bands, +1 more. Returns: object

build_quality_reportA
Read-only

Build a structured visual, semantic, coverage, and optional TOGAF report.

Aggregate counts throughout — this is the tool to poll during a
build without paying for full issue lists.

Args:
    include_togaf: Add `data.togaf_readiness`. Advisory only; see
        `assess_togaf_readiness` for the scoring scale and the
        standing `compliance_claim: false` disclaimer.
    include_quality_assurance_views: Count QA-marked views as
        stakeholder-facing in the TOGAF checks.

Returns:
    Success envelope with `data.visual_validation`,
    `data.semantic_validation` (`is_valid`, `issues_count`,
    `issue_counts`), and `data.coverage`. With `include_togaf`,
    `data.togaf_readiness` carries `status`, `score`, `max_score`,
    `advisory_findings`, `advisory_findings_count`,
    `hard_failures_count`, and `compliance_claim`.

Errors:
    `ModelNotFoundError` if no model is active.

Inputs: include_togaf, include_quality_assurance_views. Returns: object

connect_visible_relationshipsA
Idempotent

Add visual connections for every relationship whose endpoints are visible.

Iterates over every relationship in the active model and, when both
its source and target elements are already visible nodes in the
view, adds the missing visual connection. Existing connections are
skipped.

Args:
    view_id: ID of the target view.
    detail: `summary` (default) or `full`. Every relationship that
        is not drawable in this view counts as a skip, so on a
        multi-view model the skip list is close to the whole
        relationship set and every entry is expected. `full` adds
        `data.skipped_relationship_ids`.
    rollback_on_error: When true (default), restore the previous
        view state if any connection fails.

Returns:
    Success envelope with `data.connection_ids` (newly added),
    `data.added_count`, `data.skipped_count`, and `data.detail`.
    Under `full`, also `data.skipped_relationship_ids`.

Errors:
    `ModelOperationError` when `view_id` is unknown, or for an
    unknown `detail` level.

Inputs: view_id (required), detail, rollback_on_error. Returns: object

count_by_typeA
Read-only

Count active model content grouped by ArchiMate type.

Returns:
    Success envelope with `data.elements_by_type` and
    `data.relationships_by_type`, each a dict of type name to count.

Errors:
    `ModelNotFoundError` if no model is active.

Inputs: no named parameters. Returns: object

create_empty_modelA
Destructive

Create a new empty ArchiMate model and make it the active model.

Replaces any currently active model. Call this (or one of the
`load_model_*` tools) before any element/relationship/view tool.
Use `update_model` to change this metadata later, including on a
model that was loaded rather than created.

Args:
    name: Human-readable model name. Must be a non-empty string.
    description: Optional model-level documentation. Comes back as
        `data.model_info.documentation` and survives both export
        formats.
    properties: Optional model-level properties. Keys and values are
        coerced to strings.

Returns:
    Success envelope with `data.model_id` (the new model UUID) and
    `data.model_info` (same shape as `pyarchimate://activemodel/info`:
    name, id, documentation, properties, elements_count,
    relationships_count, views_count, is_loaded).

Errors:
    `INVALID_MODEL_NAME` when `name` is missing or blank.

Inputs: name (required), properties, description. Returns: object

create_model_from_specA
Destructive

Create a complete ArchiMate model from a structured JSON spec.

The spec is applied transactionally by default. Element, relationship,
and view objects accept either short field names (`type`, `source`,
`target`, `id`, `element`, `relationship`) or the long forms used by
individual tools (`element_type`, `relationship_type`, `source_id`,
`target_id`, `element_id`, `relationship_id`, `view_id`).

Spec shape:
    ```
    {
      "name": "Model Name",                    # required
      "elements": [                              # optional list
        {
          "id": "id-customer",                # optional stable ref
          "name": "Customer",                  # required
          "type": "BusinessActor",             # required
          "description": "...",               # optional
          "folder_path": "/Business",         # optional
          "properties": {"owner": "EA"}        # optional
        }
      ],
      "relationships": [
        {
          "id": "id-uses",                    # optional stable ref
          "type": "Serving",                   # required
          "source": "id-customer",             # required ref or UUID
          "target": "id-portal",               # required ref or UUID
          "name": "uses",                      # optional
          "description": "...",               # optional
          "properties": {...},                  # optional
          "access_type": "Read",                # for Access only
          "influence_strength": "+"             # for Influence only
        }
      ],
      "views": [
        {
          "id": "id-context",                  # optional stable ref
          "name": "Context",                   # required
          "folder_path": "/Views",            # optional
          "nodes": [                            # optional
            {"element": "id-customer",
             "x": 40, "y": 40,                  # x/y optional
             "width": 160, "height": 80}        # width/height optional
          ],
          "connections": [                       # optional
            {"relationship": "id-uses"}
          ],
          "connect_visible_relationships": true, # optional
          "auto_layout": true,                  # optional
          "layout_strategy": "layered_by_type", # optional
          "layout_engine": "internal"           # optional; or
                                                # "pyarchimate"
        }
      ]
    }
    ```

Args:
    spec: Specification object as described above.
    rollback_on_error: When true (default), restore the previous
        active model on any failure. Set to false to keep partial
        results.

Returns:
    Success envelope with `data` containing summary IDs of created
    model, elements, relationships, and views.

Errors:
    `INVALID_SPEC` for missing required keys.
    `InvalidElementTypeError`, `InvalidRelationshipTypeError`,
    `ElementNotFoundError`, `ModelOperationError` for validation or
    creation failures.

Inputs: spec (required), rollback_on_error. Returns: object

create_viewA

Create a new ArchiMate view (diagram) in the active model.

Views are containers for visual nodes and connections. Add nodes
with `add_node_to_view` and connections with
`add_connection_to_view` once both endpoint elements are visible.
Set a `viewpoint` so the view opens with the right Archi viewpoint
(e.g. `layered` for mixed-layer overviews, `capability` for
capability maps, `service_realization` for service views). Take the
value from `list_supported_types` (`data.viewpoints`) rather than
inferring it from the viewpoint's English name — a plausible
`business_process` is not accepted, `business_process_cooperation`
is.

Args:
    name: View name. Must be a non-empty string.
    view_id: Optional stable view ID. When omitted a UUID is
        generated. Must be unique across the
        *entire* active model — not just within this call, this
        batch, or this concept type. An id already used by any
        element, relationship, view, node or connection is
        rejected. When generating ids across several batches,
        namespace them (`bp-`, `ac-`, `tech-`) so batches cannot
        collide.
    folder_path: Optional folder path. The `Views` root is
        normalized: `Views`, `/Views`, and `views` resolve to
        `/Views`.
    viewpoint: Optional viewpoint: any canonical Archi viewpoint id
        (e.g. `layered`, `application_cooperation`) or pyArchimate
        slug. Both catalogs are in `list_supported_types` under
        `data.viewpoints`. Invalid values are rejected before the
        view is created — nothing is left behind, so the same
        `view_id` can be reused on the retry — and the error
        carries both accepted catalogs in `error.details`.

Returns:
    Success envelope with `data` shaped like a `ViewDetail`:
    `{id, name, nodes: [], connections: []}`.

Errors:
    `INVALID_VIEW_NAME` when `name` is missing or blank.
    `ModelNotFoundError` if no model is active.
    `ModelOperationError` for a duplicate `view_id`, an unknown
    `viewpoint`, or an invalid folder path.

Inputs: name (required), view_id, viewpoint, properties, +2 more. Returns: object

delete_elementA
Destructive

Delete an ArchiMate element from the active model.

pyArchimate also removes dependent concepts such as relationships
and visual nodes/connections referencing the deleted element.

Args:
    element_id: ID of the element to delete.

Returns:
    Success envelope with `data.deleted=true`.

Errors:
    `ElementNotFoundError` when `element_id` is unknown.

Inputs: element_id (required). Returns: object

delete_relationshipA
Destructive

Delete an ArchiMate relationship from the active model.

pyArchimate also removes any visual connections that referenced the
deleted relationship.

Args:
    relationship_id: ID of the relationship to delete.

Returns:
    Success envelope with `data.deleted=true`.

Errors:
    `RelationshipNotFoundError` when `relationship_id` is unknown.

Inputs: relationship_id (required). Returns: object

delete_viewA
Destructive

Delete an ArchiMate view from the active model.

Removes the view and its visual nodes/connections. Underlying
elements and relationships are NOT removed.

Args:
    view_id: ID of the view to delete.

Returns:
    Success envelope with `data.deleted=true`.

Errors:
    `ViewNotFoundError` when `view_id` is unknown.

Inputs: view_id (required). Returns: object

ensure_all_relationships_in_viewsA
Idempotent

Ensure every model relationship is rendered in at least one view.

Useful when Archi Validator reports `Unused Relation` or
`'Serving relation' is not used in a View`. The tool creates or
reuses a coverage view, adds the missing endpoint nodes, and adds
the missing connections. It also relocates redundant
Grouping-to-contained-child Aggregation/Composition connections out
of readable views into the coverage view (containment communicates
the meaning visually instead).

Coverage views are marked with the `mcp:relationship_coverage_view`
property, so future invocations recognize them regardless of the
display name.

Args:
    coverage_view_name: Name of the coverage view. If a view with
        this name exists, it is reused; otherwise it is created.
    auto_layout: When true (default), lay out the affected views
        after adding nodes and connections.
    layout_strategy: Validated for consistency with other layout
        tools but not applied — the coverage view layout is a fixed
        source/target pair grid.
    layout_engine: Must be `internal` (the default). The coverage
        layout is a fixed pair grid, so no other engine can be
        honoured here and passing one is an error rather than a
        silently ignored hint.
    rollback_on_error: When true (default), restore the previous
        model state if coverage creation fails.

Returns:
    Success envelope with `data` containing the coverage view ID,
    added node and connection counts, relocated containment
    connection counts, skipped relationship IDs, and remaining
    unused relationship IDs.

Errors:
    `ModelNotFoundError` if no model is active.
    `ModelOperationError` for an unknown layout strategy/engine
        (with `error.details.suggestions`), or for any engine other
        than `internal`. Both are validated whether or not
        `auto_layout` is true.

Inputs: auto_layout, layout_engine, layout_strategy, rollback_on_error, +1 more. Returns: object

export_elements_to_csvA
Read-only

Export all active model elements as a CSV string.

The CSV includes base columns `id`, `name`, `type`, `description`.
Custom properties are emitted as `Property:<name>` columns.

Returns:
    Success envelope with `data.csv_data` containing the CSV string.

Errors:
    `ModelNotFoundError` if no model is active.

Inputs: no named parameters. Returns: object

export_model_contentA
Idempotent

Serialize the active model as XML string content.

Use this when the caller wants the XML in the response payload. Use
`export_model_to_file` to write directly to disk.

Args:
    output_format: One of `archimate` (default, Open Group exchange
        XML), `archi` (Archi native `.archimate` XML, opens directly
        in Archi), or `xml`.
    auto_layout: When true, run layout on every view before
        serialization. Defaults to false.
    layout_strategy: Layout strategy used when `auto_layout=true`.
        One of `layered_by_type` (default, ArchiMate semantic
        lanes), `layered` (relationship-direction layered), or
        `grid`.
    layout_engine: Layout engine applied to every view when
        `auto_layout=true`. One of `internal` (default) or
        `pyarchimate` (see `auto_layout_view` for what the latter
        gives up). Per-call only: nothing about the engine is
        written into the exported file. Validated even when
        `auto_layout=false`, so a typo is never swallowed.

Returns:
    Success envelope with `data.content` (XML string),
    `data.auto_layout`, and (when `auto_layout=true`)
    `data.layout_strategy` and `data.layout_engine`.

Errors:
    `ModelNotFoundError` if no model is active.
    `UnsupportedFormatError` for an unknown `output_format`.
    `ModelOperationError` for layout or serialization failures,
        including an unknown strategy/engine (with
        `error.details.suggestions`) and a view the `pyarchimate`
        engine cannot lay out safely — one such view fails the
        whole export.

Inputs: auto_layout, quality_gate, allow_orphans, layout_engine, +5 more. Returns: object

export_model_to_fileA
Idempotent

Serialize the active model and write it to a local file.

Preferred when the user wants a `.archimate` file Archi can open
directly. Parent directories are created if missing.

Args:
    path: Output path on the MCP server's filesystem. `~` is
        expanded; relative paths resolve against the server's CWD.
    output_format: One of `archi` (default, Archi native), `archimate`
        (Open Group exchange), or `xml`.
    auto_layout: When true, lay out every view before serialization.
    layout_strategy: One of `layered_by_type` (default), `layered`,
        or `grid`. Only applied when `auto_layout=true`.
    layout_engine: One of `internal` (default) or `pyarchimate`
        (see `auto_layout_view` for what the latter gives up).
        Only applied when `auto_layout=true`, but always
        validated. Per-call only: the engine is never recorded in
        the written file.

Returns:
    Success envelope with `data.path`, `data.output_format`,
    `data.bytes_written`, `data.auto_layout`, and (when
    `auto_layout=true`) `data.layout_strategy` and
    `data.layout_engine`.

Errors:
    `ModelNotFoundError` if no model is active.
    `UnsupportedFormatError`, `ModelOperationError` for invalid
    path/format, an unknown strategy/engine (with
    `error.details.suggestions`), a view the `pyarchimate` engine
    cannot lay out safely, or serialization failure.

Inputs: path (required), auto_layout, quality_gate, allow_orphans, +6 more. Returns: object

export_relationships_to_csvA
Read-only

Export all active model relationships as a CSV string.

The CSV includes base columns `id`, `name`, `type`, `source_id`,
`target_id`. Custom properties are emitted as `Property:<name>`
columns.

Returns:
    Success envelope with `data.csv_data` containing the CSV string.

Errors:
    `ModelNotFoundError` if no model is active.

Inputs: no named parameters. Returns: object

get_relationship_compatibilityB
Read-only

Return valid ArchiMate relationship options for source and target types.

Inputs: source_type (required), target_type (required). Returns: object

get_usage_guideA
Read-only

Return the client-facing usage guide for this ArchiMate MCP server.

Call this tool when you are unsure how to operate the server. It is
intended to prevent source-code inspection: do not inspect the MCP
server source code to learn normal usage. Use this guide, prompts,
tools/list, and resources/list instead.

Returns:
    Success envelope with recommended workflows, anti-patterns,
    response conventions, and important tools.

Inputs: no named parameters. Returns: object

inspect_active_modelA
Read-only

Inspect the active model without dumping full XML or source code.

Use this immediately after loading an existing model and before
editing. It combines model info, summaries, type counts, visual
validation, compact semantic validation, compact orphan summaries,
and recommended next calls.

Args:
    include_semantic_validation: Include compact semantic validation
        summary. Defaults to true.
    include_orphans: Include compact orphan element summary.
        Defaults to true.
    sample_limit: Maximum number of issue/orphan examples to include.
        Clamped to 0-50.

Returns:
    Success envelope with compact inspection data.

Errors:
    `ModelNotFoundError` if no model is active.

Inputs: sample_limit, include_orphans, include_semantic_validation. Returns: object

list_orphan_elementsA
Read-only

List elements with no relationships and/or no view placement.

Useful for finding gaps before completing a model.

Returns:
    Success envelope with `data.elements_without_relationships`,
    `data.elements_not_in_any_view`, and `data.fully_orphan_elements`
    (each a list of element IDs), plus matching count fields.

Errors:
    `ModelNotFoundError` if no model is active.

Inputs: no named parameters. Returns: object

list_supported_typesA
Read-only

List supported ArchiMate types and configuration values.

Always call this before generating model content if you are not
certain which names the running pyArchimate build accepts. The
catalog is version-specific.

Returns:
    Success envelope with `data` containing element types grouped by
    category, relationship types, view `viewpoints` (split into
    `pyarchimate_slugs` and `archi_viewpoint_ids` — both accepted,
    and they overlap without either containing the other), folder
    roots, valid `access_type` values, valid `influence_strength`
    values, supported layout strategies, supported layout engines,
    and summary counts.

Does not require an active model.

Inputs: no named parameters. Returns: object

load_model_from_contentA
Destructive

Load an ArchiMate model from XML string content (replaces active model).

For loading large files or paths use `load_model_from_file` instead;
this tool expects the actual XML payload, not a path.

Args:
    model_content: XML content. Must start with `<` and be 10 MiB or
        smaller. DTD and entity declarations are rejected for safety.
    content_format: One of `archimate` (Open Group exchange XML,
        default), `archi` (Archi native `.archimate` XML), or `xml`.

Returns:
    Success envelope with `data.model_info` describing the loaded
    model (see `pyarchimate://activemodel/info`).

Errors:
    `INVALID_MODEL_CONTENT` when `model_content` is not XML.
    `UnsupportedFormatError` when `content_format` is not recognized.
    `ModelOperationError` when pyArchimate fails to parse the XML.

Inputs: model_content (required), content_format. Returns: object

load_model_from_fileA
Destructive

Load an ArchiMate model from a local file (replaces active model).

The preferred entry point when the user gives a local `.archimate`
or XML file path. Expects a filesystem path readable by the MCP
server process; for raw XML text use `load_model_from_content`.
By default the response includes a compact inspection (summary,
type counts, validation status, recommended next calls) so a
separate `inspect_active_model` round trip is unnecessary.

Args:
    path: Local filesystem path readable by the MCP server process.
        `~` is expanded; relative paths resolve against the server CWD.
    content_format: One of `archi` (default, Archi native
        `.archimate`), `archimate` (Open Group exchange XML), or
        `xml`.
    inspect_after_load: When true (default), include a compact model
        summary, type counts, validation status, and recommended next
        calls in the response.
    include_semantic_validation: When true (default), include a
        compact semantic validation summary when inspecting.
    sample_limit: Maximum number of issue/orphan examples to include
        in compact summaries. Clamped to 0-50.

Returns:
    Success envelope with `data.model_info`, `data.loaded_from`, and
    optionally `data.inspection`.

Errors:
    `INVALID_PATH`, `FILE_NOT_FOUND`, `FILE_READ_ERROR`,
    `UnsupportedFormatError`, or `ModelOperationError`.

Inputs: path (required), sample_limit, content_format, inspect_after_load, +1 more. Returns: object

query_elementsA
Read-only

Query elements in the active model with optional filters.

All filters are AND-combined. Pass an empty `{}` to list every
element (equivalent to the `pyarchimate://activemodel/elements`
resource).

Supported filter keys:
    - `type` (str): Match elements with this exact ArchiMate type,
      e.g. `BusinessActor`, `ApplicationComponent`.
    - `name_contains` (str): Case-insensitive substring match
      against element name.
    - `properties_contain` (dict[str, str]): Match elements whose
      custom properties contain every provided key/value pair.

Args:
    filter_criteria: Dict containing zero or more of the keys
        above. Unknown keys are ignored.

Returns:
    Success envelope with `data.elements`, a list of
    `ElementDetail` objects (`id`, `name`, `type`, `description`,
    `properties`, `folder`, `incoming_relationship_ids`,
    `outgoing_relationship_ids`).

Errors:
    `ModelNotFoundError` if no model is active.

Inputs: filter_criteria (required). Returns: object

query_relationshipsA
Read-only

Query relationships in the active model with optional filters.

All filters are AND-combined. Pass an empty `{}` to list every
relationship (equivalent to the
`pyarchimate://activemodel/relationships` resource).

Supported filter keys:
    - `type` (str): Match relationships with this exact pyArchimate
      relationship type, e.g. `Serving`, `Composition`,
      `Assignment`. The `Relationship` suffix is not used.
    - `source_id` (str): Match relationships whose source element
      UUID equals this value.
    - `target_id` (str): Match relationships whose target element
      UUID equals this value.

Args:
    filter_criteria: Dict containing zero or more of the keys
        above. Unknown keys are ignored.

Returns:
    Success envelope with `data.relationships`, a list of
    `RelationshipDetail` objects (`id`, `name`, `type`,
    `description`, `properties`, `access_type`,
    `influence_strength`, `source_element_id`,
    `target_element_id`).

Errors:
    `InvalidRelationshipTypeError` for an unknown `type`.
    `ModelNotFoundError` if no model is active.

Inputs: filter_criteria (required). Returns: object

recommend_relationshipC
Read-only

Recommend valid relationship types for source/target ids or types.

Inputs: intent, source_id, target_id, source_type, +2 more. Returns: object

render_view_to_svg_fileA
Idempotent

Render one view to an SVG file so a human can look at the diagram.

Use this when someone wants to *see* a view without opening Archi —
to check that a layout reads well, or to drop a picture into a
document or chat. Lay the view out first with `auto_layout_view` if
the geometry needs work: rendering never moves anything.

SVG is a rendering, NOT a third model format. It cannot be imported
back into Archi and it is not a substitute for
`export_model_to_file` (`archi` = Archi native `.archimate`,
`archimate` = Open Group exchange XML). Use those to persist a
model; use this to look at one view.

The markup is written to disk and never returned: an 11-element view
is already ~3.2k tokens of SVG text, and reading it back would not
tell you anything you cannot get from `summarize_view` or
`build_quality_report`. Hand the returned path to the user.

Args:
    view_id: ID of the view to render.
    path: Output path on the MCP server's filesystem (`.svg`
        conventionally). `~` is expanded, relative paths resolve
        against the server's CWD, and parent directories are
        created if missing.

Returns:
    Success envelope with `data.path`, `data.view_id`,
    `data.view_name`, `data.model_name`, `data.bytes_written`,
    `data.node_count`, `data.connection_count`, and the rendered
    canvas size in `data.width` / `data.height`. Never the markup.

Errors:
    `ModelNotFoundError` if no model is active.
    `ViewNotFoundError` when `view_id` is unknown.
    `ModelOperationError` for a blank path or a write failure.

Inputs: path (required), view_id (required). Returns: object

repair_semantic_issuesC
Destructive

Apply selected deterministic semantic relationship repairs.

Inputs: repair_ids, auto_layout, update_views, rollback_on_error, +2 more. Returns: object

summarize_modelA
Read-only

Summarize the active model: counts, view summaries, totals.

Useful for verifying generation results without dumping full XML.

Returns:
    Success envelope with `data` containing model name, total
    element/relationship/view counts, and per-view node and
    connection counts.

Errors:
    `ModelNotFoundError` if no model is active.

Inputs: no named parameters. Returns: object

summarize_viewA
Read-only

Summarize a single view: node count, connection count, gaps.

Args:
    view_id: ID of the view to summarize.

Returns:
    Success envelope with `data` containing the view name, node
    count, connection count, and relationships that could still be
    connected (both endpoints visible) but are not yet drawn.

Errors:
    `ModelNotFoundError` if no model is active.
    `ViewNotFoundError` when `view_id` is unknown.

Inputs: view_id (required). Returns: object

update_elementA
Idempotent

Update an existing ArchiMate element.

Updates is a dict containing only the fields to change. Other fields
are left untouched. Properties are merged into existing properties
(use an empty value to clear a key on subsequent updates).

Args:
    element_id: ID of the element to update.
    updates: Mapping of fields to update. Supported keys:
        - `name` (str): New element name.
        - `description` (str): New documentation text.
        - `folder_path` (str): New folder path; folder root must
          match the element's ArchiMate category.
        - `properties` (dict[str, str]): Property updates merged
          into existing properties.
        Element type cannot be changed; recreate the element to
        change its type.

Returns:
    Success envelope with the updated `ElementDetail` in `data`.

Errors:
    `ElementNotFoundError` when `element_id` is unknown.
    `ModelOperationError` for invalid folder paths.

Inputs: updates (required), element_id (required). Returns: object

update_modelA
Idempotent

Update the active model's name, documentation, and properties.

Updates is a dict containing only the fields to change; other fields
are left untouched and properties are merged into the existing ones.
There is no `model_id` parameter because exactly one model is active.
Works on a loaded model, not only on one created by this server.

Unlike `update_element`, unknown keys are rejected rather than
ignored: a mis-keyed update would silently leave model metadata
unwritten while still reporting success.

Args:
    updates: Mapping of fields to update. Supported keys:
        - `name` (str): New model name. Must be non-blank; it is
          stripped, exactly as in `create_empty_model`.
        - `description` (str): New model documentation. Reported
          back as `documentation`.
        - `documentation` (str): Accepted alias for `description`.
        - `properties` (dict[str, str]): Property updates merged
          into the existing model properties.

Returns:
    Success envelope with `data.model_info` (same shape as
    `pyarchimate://activemodel/info`).

Errors:
    `INVALID_MODEL_UPDATE` when `updates` is not an object or
        contains unsupported keys (`error.details.unsupported_keys`
        and `error.details.supported_keys` list which).
    `INVALID_MODEL_NAME` when `name` is present but not a non-blank
        string.
    `ModelNotFoundError` if no model is active.

Inputs: updates (required). Returns: object

update_relationshipA
Idempotent

Update an existing ArchiMate relationship.

Endpoints (source/target) and relationship type cannot be changed.
Recreate the relationship to change those.

Args:
    relationship_id: ID of the relationship to update.
    updates: Mapping of fields to update. Supported keys:
        - `name` (str)
        - `description` (str)
        - `properties` (dict[str, str]): merged into existing
          properties.
        - `access_type` (str): only meaningful for `Access`. One of
          `Access`, `Read`, `Write`, `ReadWrite`.
        - `influence_strength` (str): only meaningful for
          `Influence`. One of `+`, `++`, `-`, `--`, or `0`-`10`.

Returns:
    Success envelope with the updated `RelationshipDetail` in
    `data`.

Errors:
    `RelationshipNotFoundError` when `relationship_id` is unknown.
    `ModelOperationError` for unsupported access/influence values.

Inputs: updates (required), relationship_id (required). Returns: object

update_viewA
Idempotent

Update an existing ArchiMate view.

Only metadata fields can be updated; nodes and connections are
managed by `add_node_to_view`, `add_connection_to_view`, and the
layout tools.

Args:
    view_id: ID of the view to update.
    updates: Mapping of fields to update. Supported keys:
        - `name` (str): New view name.
        - `description` (str): New documentation text.
        - `properties` (dict[str, str]): Property updates merged
          into existing properties.
    viewpoint: Optional viewpoint, as on `create_view`. Validated
        before anything is applied: an unknown value leaves the
        view completely untouched, `name` and `description`
        included.

Returns:
    Success envelope with the updated `ViewDetail` in `data`.

Errors:
    `ViewNotFoundError` when `view_id` is unknown.
    `ModelOperationError` for an unknown `viewpoint`, with both
    accepted catalogs in `error.details`.

Inputs: updates (required), view_id (required), viewpoint. Returns: object

validate_modelA
Read-only

Validate visual references in the active model.

Delegates to pyArchimate's `check_invalid_conn` and
`check_invalid_nodes` helpers. Diagram-only annotation connectors
(a note line joining an Archi Note to an element) are excluded: they
have no backing relationship by design, so they are not defects. A
connector between two element-backed nodes whose relationship is
genuinely missing is still reported. Use `validate_semantics` for
ArchiMate semantic checks beyond visual references.

Returns:
    Success envelope with `data.is_valid` (bool),
    `data.invalid_connection_ids`, `data.invalid_node_ids`,
    `data.invalid_connections_count`, and
    `data.invalid_nodes_count`.

Errors:
    `ModelNotFoundError` if no model is active.

Inputs: no named parameters. Returns: object

validate_semanticsA
Read-only

Run ArchiMate semantic checks beyond visual reference validation.

Checks include invalid relationship combinations, missing node
references, duplicate element names within the same folder/type,
elements not placed in any view, and orphan service/data elements.

Args:
    detail: `summary` (default) or `full`. The completeness checks
        fire once per element and once per relationship, so a
        mid-build model with no views yet produces one issue per
        concept — 214 issues, ~55 KB, on a 71-element model — of
        which the repeated `code`, `severity` and `message` strings
        are most of the weight. Ask for `full` only when you need
        to read individual issue dicts.

Returns:
    Success envelope with `data.is_valid` (bool),
    `data.issues_count`, `data.issue_counts`, and `data.detail`.

    Under `summary`: `data.issues_by_code` maps each code to
    `{count, severity, ids}`, and `data.errors` carries the
    error-severity issues in full, so `is_valid: false` always
    arrives with its reason. There is deliberately no `data.issues`
    key — read `full` if you want that list.

    Under `full`: `data.issues`, one dict per issue.

Errors:
    `ModelNotFoundError` if no model is active.
    `ModelOperationError` for an unknown `detail` level, with close
    matches in `error.details.suggestions`.

Inputs: detail. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.5/5.0

    Scored across 45 tools

    Disambiguation4/5

    Most tools have clearly distinct purposes, such as 'add_element' vs 'add_relationship' vs 'add_node_to_view'. However, there is some overlap between 'export_model_content' and 'export_model_to_file', and between 'validate_model' and 'validate_semantics', though descriptions help differentiate them.

    Naming Consistency3/5

    Tool names use a mix of verbs like 'add', 'create', 'update', 'delete', 'export', 'load', 'query', 'validate', etc. Without a consistent verb_noun pattern, but the names are still descriptive and readable.

    Tool Count3/5

    At 45 tools, the count is high but justifiable given the complexity of ArchiMate modeling, covering CRUD for multiple entity types, validation, layout, and reporting. However, some redundancy exists with batch operations and similar query tools.

    Completeness4/5

    The tool set covers core model lifecycle: creation, editing, deletion, validation, export, and layout. Notable gaps include lack of update/delete for notes and limited folder management, but overall domain coverage is strong.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers