Skip to content
arch-lab
Integration · Model Context Protocol

An MCP server for architecture diagrams

arch-lab runs an MCP server, so Claude Code, Claude Desktop, Cursor and anything else speaking the protocol can read, write and check C4 models and sequence diagrams as .alab text. It is hosted — nothing to install, no key to configure.

endpoint
https://arch-lab.dev/api/mcp

What this is for

Your agent can already read and write files — let it edit .alab directly. This server is for the two things it cannot do alone: know the grammar exactly and get the real parser's verdict. A compiler and a reference, not a filesystem.

Connect

One transport, Streamable HTTP, at the URL above. Open yours — each entry is the whole setup:

Claude Code

One command, once. --scope user installs it for every project on your machine; use --scope project to commit it to a repo instead, or drop the flag to keep it to the current directory.

bash
claude mcp add --transport http arch-lab --scope user https://arch-lab.dev/api/mcp

Claude Desktop

Settings → Connectors → Add custom connector, then paste the URL. Or edit claude_desktop_config.json directly:

json
{
  "mcpServers": {
    "arch-lab": {
      "type": "http",
      "url": "https://arch-lab.dev/api/mcp"
    }
  }
}

Gemini CLI

One command, or add it to ~/.gemini/settings.json by hand under mcpServers with the httpUrl key (url means SSE there, which this server does not speak).

bash
gemini mcp add --transport http arch-lab https://arch-lab.dev/api/mcp

Codex CLI

Add to ~/.codex/config.toml. There is no CLI shortcut for HTTP servers, and no auth key is needed — this server does not authenticate.

toml
[mcp_servers.arch-lab]
url = "https://arch-lab.dev/api/mcp"

Cursor

Add to .cursor/mcp.json in your project, or ~/.cursor/mcp.json to get it everywhere.

json
{
  "mcpServers": {
    "arch-lab": {
      "url": "https://arch-lab.dev/api/mcp"
    }
  }
}

VS Code (Copilot)

Add to .vscode/mcp.json in your workspace, or your user mcp.json to get it everywhere.

json
{
  "servers": {
    "arch-lab": {
      "type": "http",
      "url": "https://arch-lab.dev/api/mcp"
    }
  }
}

Anything else

Any client speaking MCP over Streamable HTTP. There is no authentication and no state — every call is a pure function of its arguments.

text
https://arch-lab.dev/api/mcp

Or use the skill

Most of what this server gives an agent is knowledge — the grammar, in exact detail — and knowledge travels fine as a file. If you would rather not add a connector, the same grammar installs as an Agent Skill:

bash
npx skills add raksitnongbua/arch-lab --skill alab

It carries the grammar, but not the verdict: a file in your repository cannot tell you whether the model your agent just wrote parses, and that is what this server is for. What the skill installs, and what it cannot do.

What it can do

28 tools, all read-only — nothing here mutates anything, on your machine or ours:

Check and format C4 models

The core loop: get the real parser's verdict on what your agent wrote, then commit canonical bytes that diff cleanly.

validate_model

Validate a model

Check whether model text is valid, and if not, exactly where it breaks.

Full text the agent receives

Runs the real arch-lab parser and reports the line, column and offending source line, so a failure can be fixed directly. On success, reports what the model contains (diagrams, levels, counts) rather than echoing it back, plus any C4 review notes — missing technologies, unlabelled or vague relationships, bidirectional lines — which do not affect validity but are what a reviewer will raise. Use this after writing or editing any .alab file: it is the fastest way to confirm the result is both loadable and worth reviewing. Hand it text of another notation and it does not fail: it says which of the 10 notations the text is, names the tool that reads it, and asks the human which picture they meant — so do not "fix" line 1 of a document whose header names another kind. The header names the notation the rest of the document is written in; changing it converts nothing. A VALID model can also come back with a notation question appended, when the relationships read as numbered steps rather than as structure; the verdict and the counts still travel with it, and nothing about the document is wrong.

May ask your human when the text turns out to be one of the other eight notations, or a valid C4 model reads as an ordered sequence of steps rather than as structure.

source*
The model text: .alab, arch-lab JSON, or Mermaid C4 (max 256,000 characters).
format
Force a reading: "alab", "json" or "mermaid". Defaults to "auto", which reads the first meaningful line to decide.

format_model

Format a model canonically

Rewrite a model in its own format's canonical form — the exact bytes arch-lab itself would write, so diffs stay minimal and reviewable.

Full text the agent receives

Reports when the input was already canonical, so a no-op write can be skipped. Refuses Mermaid, which has no canonical form here. Text of another notation is not a failure here: it comes back as a question naming the tool that reads it, and asks your human which picture they meant — so do not "fix" line 1 of a document whose header names another kind. The header names the notation the rest of the document is written in; changing it converts nothing.

May ask your human when the text turns out to be one of the other eight notations.

source*
The model text: .alab, arch-lab JSON, or Mermaid C4 (max 256,000 characters).
format
Force a reading: "alab", "json" or "mermaid". Defaults to "auto", which reads the first meaningful line to decide.

Sequence diagrams

The same check-and-format loop, for message flows over time rather than C4 structure — including the `desc` continuation that keeps a message's endpoint and payload off the arrow.

validate_sequence

Validate a sequence diagram

Check whether SEQUENCE diagram text is valid, and if not, exactly where it breaks.

Full text the agent receives

Reads `.alab` sequence documents (first line `archlab 1.0 sequence`) and pasted Mermaid `sequenceDiagram` code, reporting the line, column and offending source line on failure. On success it summarises what the flow contains — participants, messages split by line style (solid/dotted) and by head style (none, arrowhead, cross, open, bidirectional), self-messages, how many messages carry a `desc` detail, fragments and their nesting depth, notes, and a FIT report — the rendered pixel size plus any labels too wide for their own arrow, which is the one defect a parse cannot see and a caller cannot look at — rather than echoing the document back. Use this for message flows over time; use `validate_model` for C4 structure diagrams. Passing a C4 document here says so and points you at the right tool. If the request could reasonably be any of those, ask the human which picture they want before writing; `list_example_models` shows one real document per notation to show them.

May ask your human when a valid flow turns out to be hub-and-spoke — four or more participants and almost every message aimed at one of them, which is a C4 context diagram drawn on a time axis.

source*
The sequence diagram text: `.alab` sequence (first line `archlab 1.0 sequence`) or Mermaid `sequenceDiagram` code (max 256,000 characters). The format is detected from the first meaningful line.

format_sequence

Format a sequence diagram canonically

Rewrite sequence text as canonical `.alab` sequence — the exact bytes arch-lab would write, so diffs stay minimal.

Full text the agent receives

Also the way to turn a pasted Mermaid `sequenceDiagram` into an `.alab` sequence document. ALL TEN of Mermaid's arrow types survive that trip in both directions (`->` `->>` `-x` `-)` `<<->>` and their dotted twins) — an arrow is two axes here too, a line style and a head style, so nothing is approximated. The import is still lossy in other ways and the response names what was dropped. Worth a call after writing a message `desc`, which is a JSON string and therefore the one place hand-escaping goes wrong: this reports the bad escape with a line and column, and returns the canonical single-line form when it is right.

source*
The sequence diagram text: `.alab` sequence (first line `archlab 1.0 sequence`) or Mermaid `sequenceDiagram` code (max 256,000 characters). The format is detected from the first meaningful line.

Flowcharts

The same check-and-format loop for step-by-step processes — plus the audit a parse cannot do: decisions whose branches carry no guard, nodes nothing reaches, and flows that stop without ending.

validate_flowchart

Validate a flowchart

Check whether FLOWCHART text is valid, and if not, exactly where it breaks.

Full text the agent receives

Reads `.alab` flowchart documents (first line `archlab 1.0 flowchart`) and pasted Mermaid `flowchart` / `graph` code, reporting the line, column and offending source line on failure. On success it summarises the graph — nodes by shape, how many arrows carry a guard, how many loop back, groups, the rendered pixel size — and audits the three defects a parse cannot see: decisions whose branches are unguarded (a diamond that asks a question and will not say which exit is which), nodes no arrow reaches, and nodes no arrow leaves that are not an `end`. Use this for step-by-step processes; use `validate_model` for C4 structure and `validate_sequence` for message flows over time. If the request could reasonably be any of those, ask the human which picture they want before writing; `list_example_models` shows one real document per notation to show them.

source*
The flowchart text: `.alab` flowchart (first line `archlab 1.0 flowchart`) or Mermaid `flowchart` / `graph` code (max 256,000 characters). The format is detected from the first meaningful line.

format_flowchart

Format a flowchart canonically

Rewrite flowchart text as canonical `.alab` flowchart — the exact bytes arch-lab would write, so diffs stay minimal.

Full text the agent receives

Also the way to turn pasted Mermaid `flowchart` / `graph` code into an `.alab` flowchart document, which is a one-way lossy import: the response names what was dropped, including the direction (`LR` and friends are layout, not model) and any node shape with no arch-lab counterpart.

source*
The flowchart text: `.alab` flowchart (first line `archlab 1.0 flowchart`) or Mermaid `flowchart` / `graph` code (max 256,000 characters). The format is detected from the first meaningful line.

Use-case diagrams

The same check-and-format loop for who may do what at a system's edge — plus the audit UML cares about: actors that can do nothing, capabilities nothing reaches, and include/extend cycles.

validate_usecase

Validate a use-case diagram

Check whether UML USE-CASE text is valid, and if not, exactly where it breaks.

Full text the agent receives

Reads `.alab` use-case documents (first line `archlab 1.0 usecase`) and pasted Mermaid written in the actor/use-case convention, reporting the line, column and offending source line on failure. On success it summarises who can do what — actors, use cases, associations, «include»/«extend» dependencies, generalizations, each boundary's contents and the rendered pixel size — then audits the defects a parse cannot see: actors with no association at all, use cases nothing can reach, capabilities sitting outside every boundary, empty boundaries, and include/extend or generalization CYCLES, which UML forbids. Use this for who-may-do-what at a system's edge; use `validate_model` for C4 structure, `validate_sequence` for message flows and `validate_flowchart` for step-by-step processes. If the request could reasonably be any of those, ask the human which picture they want before writing; `list_example_models` shows one real document per notation to show them.

source*
The use-case diagram text: `.alab` usecase (first line `archlab 1.0 usecase`) or Mermaid using the actor/use-case convention (circle actors, stadium use cases, a subgraph boundary) (max 256,000 characters). The format is detected from the first meaningful line.

format_usecase

Format a use-case diagram canonically

Rewrite use-case text as canonical `.alab` usecase — the exact bytes arch-lab would write, so diffs stay minimal.

Full text the agent receives

Also the way to turn pasted Mermaid into an `.alab` use-case document, which is a one-way lossy import: the response names what was dropped, including the arrowheads Mermaid draws on lines that are undirected associations in UML.

source*
The use-case diagram text: `.alab` usecase (first line `archlab 1.0 usecase`) or Mermaid using the actor/use-case convention (circle actors, stadium use cases, a subgraph boundary) (max 256,000 characters). The format is detected from the first meaningful line.

ER diagrams

The same check-and-format loop for what a system stores — plus the audit a parse cannot do: foreign keys with no line saying what they reference, tables with no primary key, and tables joined to nothing. The one kind whose Mermaid conversion is two-way and total.

validate_er

Validate an ER diagram

Parse an entity-relationship diagram and report what a schema reviewer would: the tables, their column counts and their keys, the cardinality on every relationship, and the rendered size.

Full text the agent receives

Then the audit a parse cannot do — foreign-key columns with no relationship line saying what they reference, tables with no primary key, tables joined to nothing, and self-joins. Reads `.alab` er documents (first line `archlab 1.0 er`) and pasted Mermaid `erDiagram` code. Use `validate_model` for C4 structure, `validate_sequence` for message flows, `validate_flowchart` for processes and `validate_usecase` for actors at a system's edge. If the request could reasonably be any of those, ask the human which picture they want before writing; `list_example_models` shows one real document per notation to show them.

source*
The ER diagram text: `.alab` er (first line `archlab 1.0 er`) or Mermaid `erDiagram` code (max 256,000 characters). The format is detected from the first meaningful line — both dialects have a real header, so nothing here is guessed.

format_er

Format an ER diagram canonically

Rewrite ER text as canonical `.alab` er — the exact bytes arch-lab would write, so diffs stay minimal.

Full text the agent receives

Also the way to turn pasted Mermaid `erDiagram` code into an `.alab` document. UNLIKE the flowchart and use-case imports, this conversion is TWO-WAY AND TOTAL over the diagram: Mermaid has a real erDiagram, so both cardinalities, the solid/dashed line and every column with its type, key roles and comment all survive. Only metadata is dropped, and the response says which.

source*
The ER diagram text: `.alab` er (first line `archlab 1.0 er`) or Mermaid `erDiagram` code (max 256,000 characters). The format is detected from the first meaningful line — both dialects have a real header, so nothing here is guessed.

Data dictionaries

The same check-and-format loop for what a field MEANS and where its value comes from — plus the number no other tool here reports: how many of your fields are actually documented.

validate_dict

Validate a data dictionary

Parse a data dictionary and report what a reviewer would: the sections, how many fields each holds, and — the headline number — how many of those fields actually carry a description.

Full text the agent receives

Then the coverage audit: fields with no meaning given (a name and a type and no description is a schema dump, not a dictionary), fields with no `source`, fields marked deprecated without saying what replaces them, and an enumeration of every field flagged `pii`. Reads `.alab` dict documents (first line `archlab 1.0 dict`). If the request could reasonably be any of those, ask the human which picture they want before writing; `list_example_models` shows one real document per notation to show them.

source*
The data dictionary text: `.alab` dict (first line `archlab 1.0 dict`) (max 256,000 characters). There is no Mermaid dialect for this kind — Mermaid has no dictionary notation, so none was invented.

format_dict

Format a data dictionary canonically

Rewrite dictionary text as canonical `.alab` dict — the exact bytes arch-lab would write, so diffs stay minimal.

Full text the agent receives

There is no Mermaid import for this kind: Mermaid has no dictionary notation.

source*
The data dictionary text: `.alab` dict (first line `archlab 1.0 dict`) (max 256,000 characters). There is no Mermaid dialect for this kind — Mermaid has no dictionary notation, so none was invented.

Gantt charts

The same check-and-format loop for how long work takes and what blocks what — plus the two answers only arithmetic can give: the critical path, and the dependency cycles that would make it a fiction. Mermaid `gantt` converts both ways in the app; these tools answer in `.alab`.

validate_gantt

Validate a gantt

Parse a GANTT CHART and report what a planner would: how long the plan runs, the calendar dates it spans when it has a `starts` line, and — the number nobody can read off their own text — the CRITICAL PATH, the chain of items that decides the end date.

Full text the agent receives

Then the audit a parse cannot do: dependency CYCLES (a waits on b waits on a), which the parser deliberately does not look for and which make the schedule meaningless; `after` entries that constrain nothing because a sibling already waits for them; sections holding only milestones, so the band draws no bar at all; and, as information rather than a fault, items whose float exceeds their own duration. Reads `.alab` gantt documents (first line `archlab 1.0 gantt`) and pasted Mermaid `gantt` code, naming on success what that import normalised. How long each piece takes, and what can't start until it's done. Use `validate_flowchart` for the order of steps with no duration, and `validate_sequence` for messages over time. If the request could reasonably be any of those, ask the human which picture they want before writing; `list_example_models` shows one real document per notation to show them.

source*
The gantt text: `.alab` gantt (first line `archlab 1.0 gantt`) or Mermaid `gantt` code (max 256,000 characters). The format is detected from the first meaningful line — both dialects have a real header, so nothing here is guessed. The import is lossy in named ways: the earliest date becomes the document origin and every other position becomes a whole number of days from it, and Mermaid's `crit` tag reads as the `at-risk` state (arch-lab computes the critical path, so no tag declares it). This tool always answers in `.alab`.

format_gantt

Format a gantt canonically

Rewrite gantt text as canonical `.alab` gantt — the exact bytes arch-lab would write, so diffs stay minimal.

Full text the agent receives

Also the way to turn pasted Mermaid `gantt` code into an `.alab` gantt. That import is LOSSY IN NAMED WAYS and the response lists them; this tool always answers in `.alab`, as every `format_*` tool here does. Mermaid's `crit` tag imports as the `at-risk` STATE — in Mermaid it is a decoration the author types, which is what `at-risk` is here — and NOT as a critical path: arch-lab computes that from durations and dependencies, so no tag declares it and `validate_gantt` is where the chain is reported. `crit` on a task already tagged `done` loses the `crit`, since a finished task is no longer at risk. Refused BY NAME rather than approximated, each because it would make the chart mean something else: `excludes`, `includes`, `weekend`, `weekdays`, `todayMarker`, `weekday`, `axisFormat`, `tickInterval`, `inclusiveEndDates` (a working week, an axis granularity or an end-date meaning arch-lab derives or fixes itself), `until` (an item here has a length, not an end tied to another task), sub-day durations (`ms`, `s`, `m`, `h`), and a `dateFormat` other than `YYYY-MM-DD`. Gantt charts travel as `.alab` text, as Mermaid (a plan needs a `starts` date to become one — Mermaid `gantt` has no relative axis), or as a share link.

source*
The gantt text: `.alab` gantt (first line `archlab 1.0 gantt`) or Mermaid `gantt` code (max 256,000 characters). The format is detected from the first meaningful line — both dialects have a real header, so nothing here is guessed. The import is lossy in named ways: the earliest date becomes the document origin and every other position becomes a whole number of days from it, and Mermaid's `crit` tag reads as the `at-risk` state (arch-lab computes the critical path, so no tag declares it). This tool always answers in `.alab`.

Milestone timelines

The same check-and-format loop for what happened and in what order — plus the two findings only this tool can make: periods written out of sequence, which nothing else here reads a period label closely enough to notice, and events carrying a duration or a dependency in their label, which is the document asking to be a gantt. Mermaid `timeline` goes both ways.

validate_timeline

Validate a milestone timeline

Parse a MILESTONE TIMELINE — events as points, grouped into named periods — and report the audit a parse cannot do.

Full text the agent receives

Two of its findings exist nowhere else in arch-lab. PERIODS OUT OF ORDER: this notation never reads a period label as a date, so nothing else notices that `2024, 2019, 2025` is written out of sequence, and the diagram draws declaration order confidently. EVENTS CARRYING A DURATION OR A DEPENDENCY in their label ("three weeks", "after the freeze") — these parse perfectly and are the sign the document wants to be a gantt. Then: the same event label twice inside one period, labels that wrap past three lines when drawn, and — as information rather than a fault — periods holding a single event. Reads `.alab` timeline (first line `archlab 1.0 timeline`) and pasted Mermaid `timeline` code. What happened when, and which period it happened in. Use `validate_gantt` when the work has lengths and prerequisites, and `validate_sequence` for messages between participants over time. If the request could reasonably be any of those, ask the human which picture they want before writing; `list_example_models` shows one real document per notation to show them.

source*
The timeline text: `.alab` timeline (first line `archlab 1.0 timeline`) or Mermaid `timeline` code (max 256,000 characters). The format is detected from the first meaningful line — both dialects have a real header, so nothing here is guessed. The import keeps every period and event; this tool answers in `.alab`.

format_timeline

Format a milestone timeline canonically

Rewrite timeline text as canonical `.alab` timeline — the exact bytes arch-lab would write, so diffs stay minimal.

Full text the agent receives

Also the way to turn pasted Mermaid `timeline` code into an `.alab` timeline. Mermaid holds everything a timeline says — a period is a label and an event is a label — so nothing about the diagram is approximated in either direction. Import normalises two spellings rather than losing them — a continuation row (a line beginning `:`) folds into the period above it, and `<br>` becomes a real newline — and refuses BY NAME `section` (Mermaid groups periods one level above the period; arch-lab has only the period itself, so flattening would either strand the period labels or merge bands you separated) and a period row listing no events. Export drops what `timeline` has nowhere to put: an event's `desc` and its `#tag`s. Timelines travel as `.alab` text, as Mermaid, or as a share link.

source*
The timeline text: `.alab` timeline (first line `archlab 1.0 timeline`) or Mermaid `timeline` code (max 256,000 characters). The format is detected from the first meaningful line — both dialects have a real header, so nothing here is guessed. The import keeps every period and event; this tool answers in `.alab`.

Lifecycles

The same check-and-format loop for one thing moving through states — plus the findings only this tool can make: a subject that never terminates, states stranded after a final one, branches with no condition on them, and states named as ACTIONS, which is a flowchart written in the wrong notation. No Mermaid dialect exists for this one, and none was invented.

validate_lifecycle

Validate a lifecycle

Parse a LIFECYCLE — one named subject, the ordered states it passes through, and the branches that leave that track — and report the audit a parse cannot do.

Full text the agent receives

Every finding describes a document that parses and is still wrong. THE SUBJECT NEVER TERMINATES: nothing carries `ends`, so the document says the subject reaches the last state and stays there. UNREACHABLE STATES: `ends` means the subject stops, so anything declared after a final state is stranded — each line is valid alone and only the pair is wrong. BRANCHES NOBODY KNOWS HOW TO TAKE: an `exit` with no `when` draws a departure and refuses to say what causes it. STATES THAT READ AS STEPS: a state is a place the subject can BE ("Paid"), not something somebody does ("Take payment") — a document of imperatives is a flowchart written in this notation, and this is the only place that will say so. And, when there are no branches at all, that the document is a milestone timeline. Reads `.alab` lifecycle only. What one thing went through, and where it can end up. Use `validate_flowchart` when the picture is steps and decisions rather than one thing moving, and `validate_timeline` when nothing branches. If the request could reasonably be any of those, ask the human which picture they want before writing; `list_example_models` shows one real document per notation to show them.

source*
The lifecycle text: `.alab` lifecycle (first line `archlab 1.0 lifecycle`) — the only dialect (max 256,000 characters). There is NO Mermaid equivalent and none was invented: `stateDiagram-v2` is a state MACHINE (every transition that could happen, from anywhere to anywhere), not one subject's ordered history with a main track, and `journey` scores satisfaction. Importing either would mean inventing a track its author never wrote.

format_lifecycle

Format a lifecycle canonically

Rewrite lifecycle text as canonical `.alab` lifecycle — the exact bytes arch-lab would write, so diffs stay minimal.

Full text the agent receives

ONE DIALECT IN AND ONE OUT: there is no Mermaid lifecycle to convert from or to, for the reason `validate_lifecycle` gives. What the grammar refuses BY NAME, each because accepting it would make this an arbitrary graph — which is the flowchart: an edge between two states (`to`, `next`, `then`, `goes`, `after` — the track IS the order the states are written in), a `rejoins` naming a state declared LATER (a forward shortcut along the track), an `exit` nested inside another (branch depth is one), and a second `subject`. Lifecycles travel as `.alab` text or as a share link.

source*
The lifecycle text: `.alab` lifecycle (first line `archlab 1.0 lifecycle`) — the only dialect (max 256,000 characters). There is NO Mermaid equivalent and none was invented: `stateDiagram-v2` is a state MACHINE (every transition that could happen, from anywhere to anywhere), not one subject's ordered history with a main track, and `journey` scores satisfaction. Importing either would mean inventing a track its author never wrote.

Convert and inspect

Move a model between formats, or read its shape without paying for its full text.

convert_model

Convert between formats

Convert a C4 model to .alab, arch-lab JSON, or Mermaid C4.

Full text the agent receives

.alab and JSON are lossless in both directions. Mermaid is a one-way, lossy export of a SINGLE diagram (geometry, tags, icons, drill-down links and traceability are dropped) — good for embedding a picture in a README, never as a source of truth. C4 models only: a sequence document has no Mermaid export here (Mermaid sequenceDiagram is import-only, via format_sequence) — sequence documents travel as .alab text. Text of another notation is not a failure here: it comes back as a question naming the tool that reads it, and asks your human which picture they meant — so do not "fix" line 1 of a document whose header names another kind. The header names the notation the rest of the document is written in; changing it converts nothing.

May ask your human when the text turns out to be one of the other eight notations, or a Mermaid export was asked for on a model with several diagrams whose root is too thin to be the one anybody meant.

source*
The model text: .alab, arch-lab JSON, or Mermaid C4 (max 256,000 characters).
format
Force a reading: "alab", "json" or "mermaid". Defaults to "auto", which reads the first meaningful line to decide.
to*
Target format: "alab", "json" or "mermaid". `.alab` and JSON convert both ways losslessly; Mermaid is a one-way, lossy export of one diagram.
diagram_id
Which diagram to emit, for to="mermaid" only. Omitting it is safe when the model has one or two diagrams, or when its root holds the picture you mean: the root is then used. On a model with three or more diagrams whose root is a bare signpost, the tool STOPS and lists the diagrams with their counts rather than emitting the one that contains none of the detail. Naming an id never asks — it is taken as the choice already made.

describe_model

Describe a model's structure

Read the shape of a model without paying for its full text: metadata, totals, and the drill-down hierarchy of diagrams.

Full text the agent receives

Use this to orient in an unfamiliar model, or to find which diagram a change belongs in, before fetching or editing anything. Text of another notation is not a failure here: it comes back as a question naming the tool that reads it, and asks your human which picture they meant — so do not "fix" line 1 of a document whose header names another kind. The header names the notation the rest of the document is written in; changing it converts nothing.

May ask your human when the text turns out to be one of the other eight notations.

source*
The model text: .alab, arch-lab JSON, or Mermaid C4 (max 256,000 characters).
format
Force a reading: "alab", "json" or "mermaid". Defaults to "auto", which reads the first meaningful line to decide.
include_contents
Also list every boundary, node and edge of every diagram, in .alab form. Defaults to false, which returns the hierarchy only.

Learn the format

The grammar, the icon vocabulary and real examples — read these before writing .alab, not after the first failure.

get_syntax_reference

Get the .alab grammar

The .alab grammar for c4, sequence, gantt, timeline, lifecycle documents, generated from examples verified against the real parser on every build.

Full text the agent receives

Read it BEFORE writing one of those by hand — significant indentation and order-free attributes are easy to guess wrong. It does NOT cover the other 5 notations (flowchart, usecase, er, dict, tree): for those, fetch a bundled document with list_example_models and get_example_model, which is the parser-verified reference for their grammar. Also available as the resource archlab://syntax.

section
One of: overview, example, layout, header, diagrams, frames, nodes, edges, paths, unknown-fields, sequence, gantt, timeline, lifecycle, errors. Omit for the whole reference.

list_icons

List node icons

The vocabulary the `@icon` token draws from — every slug a node can cite, searchable by name, slug or alias.

Full text the agent receives

Call this BEFORE writing an `@slug` on a node line, because a wrong slug is the one authoring mistake no validator will ever report: an unknown slug does not fail anywhere — the canvas silently falls back to the node type's generic icon — so a guessed `@postgres` quietly renders the wrong picture (searching "postgres" finds the real slug, `postgresql`). Icons this registry lacks can be supplied by the document itself with a `customicon <slug> "Name" "<svg>…"` header line — see the header section of the syntax reference. A query with several plausible matches and nothing actually CALLED that comes back as a question for you to ask your human, not a list: do not take the first. ("postgres" is a declared alias and resolves silently; "sql" names nothing and asks.)

May ask your human when a query matches two to five icons and none of them is called that — a wrong `@slug` never errors anywhere, so nothing downstream would ever report the guess.

query
Case-insensitive substring, matched against each icon's name, slug and aliases — "pg" and "postgres" both find PostgreSQL. Omit for the full vocabulary.
category
Restrict to one category: languages, databases, messaging, networking, cloud, devops, observability, saas, generic. Omit to search all of them.

list_example_models

List example documents

Every complete, real document arch-lab ships, grouped by notation — all 10 of them, not just C4 — each with what it holds, counted from the parsed document.

Full text the agent receives

THE TOOL TO CALL WHEN A REQUEST FITS MORE THAN ONE NOTATION: the grouping says what each kind is for and each entry is a real document, so it is what to show a human who has to choose — and what stops an agent that only knows arch-lab draws C4 from writing a plan, a schema or a lifecycle as boxes and lines. Ids are unique across every notation, so an id alone names a document.

No arguments.

get_example_model

Get an example document

Fetch one bundled example in full, in any notation — the tool resolves the id across every registry and says which notation it found, so use one as a pattern for idiomatic structure rather than inventing a shape.

id*
The example's id, from list_example_models (e.g. "shopflow", a C4 model, or "store-migration", a gantt). One flat namespace: no notation argument is needed or accepted.
format
"alab" (default) — the .alab text, in the notation's own grammar, which is what to edit and what every writer tool reads. "json" — the parsed document. For a C4 model that is arch-lab JSON, a file format the readers accept; for the other kinds it is the parser's own shape, good for inspecting and NOT an input format, which the response says on every such fetch.

Decomposition trees

The same check-and-format loop for a breakdown of any depth — plus the findings only this tool can make: a level that splits nothing, a row that fills none of the columns the document promised, and a branch far deeper than its siblings. No Mermaid dialect is accepted yet.

validate_tree

Validate a decomposition tree

Check whether `.alab` tree text is valid, and if not, exactly where it breaks.

Full text the agent receives

On success, reports the shape — how many nodes, how many are leaves, how deep it runs — plus the defects a parse cannot see: a branch with one child, which is a rename rather than a breakdown; a leaf that fills none of the columns the document promised; depths left unnamed when others are named; and one branch far deeper than its siblings. What breaks down into what, all the way down.

source*
The tree text: `.alab` tree (first line `archlab 1.0 tree`) (max 256,000 characters). There is no Mermaid dialect accepted here yet: Mermaid's `mindmap` is a tree, but it carries labels with no ids and no columns, so importing it can only ever be one-way and it is not built. This tool answers in `.alab`.

format_tree

Format a decomposition tree

Rewrite `.alab` tree text into its canonical form — one indent step per level, continuations in schema order, trailing empty cells trimmed.

Full text the agent receives

Byte-identical on text that is already canonical, so it is safe to run on every save.

source*
The tree text: `.alab` tree (first line `archlab 1.0 tree`) (max 256,000 characters). There is no Mermaid dialect accepted here yet: Mermaid's `mindmap` is a tree, but it carries labels with no ids and no columns, so importing it can only ever be one-way and it is not built. This tool answers in `.alab`.

Choosing a notation

Which document kind answers the request, and what separates the ones readers confuse. Read before writing, not after.

choose_notation

Choose a notation

Which of the 10 notations answers this request.

Full text the agent receives

Returns the QUESTION each one answers, the fact that separates the pairs readers actually confuse (C4 against a tree, a gantt against a timeline, a flowchart against a lifecycle), the header line each document opens with, and the validator to check it with. Call this BEFORE writing any `.alab`, when a request could fit more than one kind. It deliberately does not rank: it has one sentence and you have the conversation behind it, so a confident wrong ranking would be worse than none. If two still fit, put both to your human.

No arguments.

Show a human

Turn a finished document in any notation into a link that opens the diagram in the viewer.

Resources & prompts

Clients that would rather pin reference material than call for it can read the grammar as a resource:

  • archlab://syntax

    The complete .alab grammar as Markdown, every example verified against the real parser. Pin this when authoring models.

And one prompt, for the whole authoring procedure rather than a single call:

  • author_c4_model

    A working procedure for producing a valid .alab model of a system: read the grammar, draft the levels, validate, then share.

    Arguments: system, levels (optional)

A good workflow

The order that avoids rework, whether you drive it yourself or use the author_c4_model prompt:

  1. get_syntax_reference first. .alab has significant indentation and order-free attributes; writing it from memory produces plausible, invalid files.
  2. get_example_model to see idiomatic structure at a real scale before inventing one.
  3. Write the file with your own editing tools. Omit geometry — the defaults are deterministic and lossless.
  4. validate_model until it passes. Every failure comes back with a line, a column and the offending source line.
  5. format_model so the committed file is canonical and diffs cleanly, then create_share_link so a human can actually look at the diagram.

Privacy & limits

  • Nothing is stored. Every tool is a pure function of the text you send it — no database, no account, no history.
  • Share links do not upload your model. It is compressed into the URL fragment (after #), which browsers never transmit. Opening one renders entirely in the recipient's browser.
  • No authentication. The endpoint holds no secrets and reads nothing but its arguments, so there is no key to manage. Do not send a model you would not paste into a public form.
  • 256,000-character ceiling on a single model — several times larger than anything anyone has authored. Past it, split it with childRef.
  • Mermaid is one-way. Importing Mermaid C4 and sequenceDiagram works; exporting drops geometry, tags, icons, drill-down links and traceability, and for sequence there is no export at all. Keep .alab or .archlab.json as the source of truth.
  • What you may pin. The endpoint URL, the tool names and their arguments are stable — none of them is renamed or dropped without a major release. Response wording is not: it is prose written for a reader, and it is reworded whenever a clearer sentence exists. Match on what a tool documents it returns, never on the exact text it says it in.

The grammar is documented at /syntax, and you can check a model by hand at /validate — the same checker this server calls.