Skip to main content
Glama

C4Loom

Weave architecture into diagrams.

A local-first MCP server that generates real C1-C4 diagrams, not just diagram text.

CI MIT license Node.js 22+ Java 21+ MCP stdio Local first

Quick start · Diagram gallery · Connect your agent · MCP tools · Contributing

Why C4Loom?

Writing a Structurizr workspace is only part of the job. C4Loom takes the next step: it validates an explicit architecture model, runs actual rendering engines, and returns editable sources, transparent images, and an offline viewer through the Model Context Protocol.

Your agent supplies the architectural facts. C4Loom turns those facts into inspectable artifacts, with a unique run directory and SHA-256 hashes.

Capability

What you get

All four C4 levels

System context, containers, components, and explicit code detail.

Native Structurizr rendering

C1-C3 rendered with Structurizr's own browser visualization.

Real code diagrams

C4 rendered by PlantUML/Smetana and linked to its component as an image view.

Transparent exports

SVG and PNG with transparent outer canvases and checked PNG alpha.

Editable outputs

Architecture JSON, Structurizr DSL/JSON, and PlantUML source.

Traceable runs

Artifact hashes, engine fingerprints, events, and image verification receipts.

Local-first operation

No hosted renderer, embedded LLM, API key, Docker, or Graphviz required.

Optional official validation

Connect the official Structurizr MCP as an additional structural validator.

Related MCP server: Excalidraw Architect MCP

These diagrams are generated from the executable C4Loom self-architecture example. They describe this tool, not a fictional application.

C1 · System context

C2 · Containers

C4Loom system context

C4Loom container diagram

C3 · MCP server components

C4Loom component diagram

C4 · Architecture compiler modules

C4Loom code diagram

Quick start

Prerequisites

  • Node.js 22+ and npm.

  • Java 21+, available as java or configured through C4_JAVA.

  • Git, and internet access for the initial dependency and engine downloads.

  • Enough disk space for the engines, Chromium, dependencies, and generated runs.

Install and generate

git clone https://github.com/h0w4r/c4loom.git
cd c4loom
npm ci
npm run setup
npx playwright install chromium
npm run demo

On Linux, install browser system libraries with npx playwright install --with-deps chromium when needed.

The demo connects through a real MCP stdio client, generates all four levels, and prints the output directory, manifest, and viewer paths. Open the resulting viewer/index.html in a browser to navigate the model.

The repository is public, but the npm package is intentionally marked private: install from Git; no published npm package is required.

Connect your agent

Any MCP client supporting stdio

Use absolute paths appropriate to your machine:

{
  "mcpServers": {
    "c4loom": {
      "command": "node",
      "args": ["/absolute/path/to/c4loom/src/server.mjs"],
      "env": {
        "C4_OUTPUT_ROOT": "/absolute/path/to/diagram-output"
      }
    }
  }
}

On Windows, use forward-slash paths such as C:/tools/c4loom/src/server.mjs. The enclosing configuration format varies by client; the command, arguments, and environment above are the stdio connection settings.

The server reserves stdout for MCP JSON-RPC and writes progress to stderr. If node or java is unavailable in the client's environment, specify its absolute executable path.

Codex project configuration

npm run configure -- --project /absolute/path/to/your/project

This adds a c4loom entry to that project's .codex/config.toml, without changing global settings or replacing existing server entries. If the entry already exists, the command stops without changing it.

With no --project argument, it registers in the C4Loom checkout itself. The target project must be trusted by Codex. Reload MCP connections or start a new session if the client was already open.

Example request to your agent

Use C4Loom to generate the four C4 levels for this repository. Inspect the implementation first, build an explicit architecture model, and do not invent components or code members. Return the PNG/SVG paths and the offline viewer.

The agent must map verified architectural facts into the tool's model schema. C4Loom does not reverse-engineer a repository by itself.

MCP tools

Tool

Input

Result

generate_c4

project, model, optional levels

Real C1-C4 diagrams, editable sources, viewer, and manifest.

render_structurizr

project, self-contained dsl

Real C1-C3 images from an existing workspace.

read_artifact

Absolute artifact path

A PNG image or supported text artifact inside the output root.

check_runtime

No arguments

Engine hash verification and configured runtime information.

levels defaults to [1, 2, 3, 4]. A full request requires declared containers, components, and at least one explicit code view. For a model without code detail, request only the supported lower levels instead of inventing it.

check_runtime verifies engine files; it does not prove that Java, Chromium, the MCP client, and image generation work together. Run the demo or E2E suite to test the complete path.

Architecture model

Field

Meaning

model.title, model.description

Workspace identity and purpose.

model.focalSystem

Identifier of the system to detail.

model.people[]

People with id, name, and description.

model.systems[].containers[]

Systems and their containers.

model.systems[].containers[].components[]

Components within each container.

model.relationships[]

Explicit source, target, description, and optional technology.

model.codeViews[]

Code views attached to components in the focal system.

model.codeViews[].elements[]

Classes, interfaces, modules, procedures, or records.

model.codeViews[].relationships[]

Dependencies, associations, composition, or inheritance.

See the complete working model and the schema and compiler. Identifiers must start with an ASCII letter and contain only ASCII letters, numbers, or underscores. References must point to declared elements. Names and descriptions preserve the supplied language; generated C4 terminology defaults to English.

What each run produces

output/<project>/<run-id>/
├── architecture.json
├── workspace.dsl
├── workspace.json
├── manifest.json
├── diagrams/
│   ├── C1_context.svg / .png / .image.json
│   ├── C2_containers.svg / .png / .image.json
│   ├── C3_<container>.svg / .png / .image.json
│   └── C4_<view>.puml / .svg / .png / .image.json
└── viewer/
    └── index.html + local viewer assets

Each generation gets a new UUID directory. The manifest records engine versions, requested views, rendering events, artifact sizes, and SHA-256 hashes. Image receipts record dimensions, visible pixels, and corner alpha. Run directories also preserve engine logs for diagnosis.

Transparency applies to the outer canvas. Diagram nodes, component boundaries, and other intentional visual elements may retain their own fills.

How it works

  1. Validate the explicit architecture contract and element references.

  2. Compile Structurizr DSL and code-view PlantUML.

  3. Render C4 locally with PlantUML's Smetana layout engine.

  4. Parse and export the complete workspace with the official Structurizr engine.

  5. Render C1-C3 using the native Structurizr browser export API in Chromium.

  6. Verify and persist transparent images, editable sources, viewer, and manifest.

The C4 code view is a PlantUML-rendered image associated with a Structurizr component. It is not presented as a native Structurizr UML renderer.

Local-first by default

Rendering uses local engines and browser assets. By default, architecture models are not sent to an external validation or rendering service. Initial installation downloads dependencies, Chromium, and pinned engine artifacts.

Imported DSL is deliberately restricted: no executable ! directives, workspace inheritance, external URLs, themes, icons, or image resources. Artifact reads are confined to the configured output root, including checks against escaping links and junctions. Run C4Loom with trusted local clients; these checks are not a general-purpose hostile-code sandbox.

Optional official Structurizr MCP

Set C4_OFFICIAL_MCP_URL to add the official server's validate tool to the pipeline. The validator must return OK; rejection or connection failure stops the run rather than silently skipping a configured dependency.

Loopback endpoints work without extra opt-in. Non-loopback endpoints also require C4_ALLOW_REMOTE_OFFICIAL=1. Enabling one sends the structural DSL to that service.

This supplementary validation excludes local C4 image references because the official MCP parser restricts filesystem access. The local Structurizr parser still validates the complete workspace, and PlantUML renders the code detail. The manifest records the validation scope explicitly.

Configuration

Variable

Default / purpose

C4_OUTPUT_ROOT

<checkout>/output; allowed root for generated runs and artifact reads.

C4_RUNTIME_DIR

<checkout>/.runtime; pinned engines and engines.json.

C4_JAVA

java; optional Java executable override.

C4_CHROMIUM

Playwright-managed Chromium; optional executable override.

C4_NODE_MODULES

Optional externally managed Node package directory.

C4_IDLE_MS

120000; engine inactivity window, not total execution time.

C4_DOWNLOAD_IDLE_MS

120000; download inactivity window.

C4_CONNECT_MS

20000; official MCP connection/request wait, renewed by tool progress.

C4_OFFICIAL_MCP_URL

Unset; optional official MCP endpoint.

C4_ALLOW_REMOTE_OFFICIAL

Unset; set to 1 to permit a non-loopback validator.

The Codex registration helper explicitly sets the target project's output root to .local/c4loom, separate from the direct server default above.

Pinned engines

Engine

Version

Download source

Structurizr

2026.09.19

Official Structurizr distribution.

PlantUML MIT

1.2026.9

Maven Central plantuml-mit artifact.

npm run setup verifies pinned SHA-256 digests before reuse. The PlantUML digest was checked against Maven Central. The Structurizr pin records the reviewed official HTTPS download; it is not a vendor signature. Engine binaries and node_modules are not committed.

Testing

npm test
npm run test:e2e

The E2E suite uses the real MCP SDK over stdio and actual engines. It checks invalid-input rejection, a real Structurizr parser failure, recovery in the same session, C1-C4 generation, artifact hash read-back, PNG retrieval through MCP, an outside-root read rejection, and navigation across all four native viewer views. PNG transparency checks run during generation.

Local test evidence is written to .evidence/ and ignored by Git. CI runs unit and real rendering tests on Windows and Linux; the badge reports the actual workflow status rather than a hardcoded passing label.

Troubleshooting

Symptom

What to check

Missing engines

Run npm run setup in the checkout used by the client.

Java launch/version error

Install Java 21+ and check java -version or C4_JAVA.

Chromium executable missing

Run npx playwright install chromium as the same OS user.

Browser libraries missing on Linux

Run npx playwright install --with-deps chromium.

Missing code view

Declare model.codeViews or request only levels [1, 2, 3].

MCP tools not visible

Check absolute paths, project trust, and reconnect the client.

Official validation fails

Check the endpoint and enabled DSL tools; inspect the run diagnosis.

Failed runs keep available diagnostics in their output directory. Long engine work is monitored for activity rather than cancelled solely for elapsed time.

Project layout

src/model.mjs       Model schema, validation, DSL and PlantUML compilation
src/pipeline.mjs    Generation, optional validation, manifests, artifact reads
src/render.mjs      Native Structurizr export, code rendering, transparent PNG
src/runtime.mjs     Engine integrity, path boundaries, process supervision
src/server.mjs      Four MCP tools over stdio
scripts/            Setup, project registration, demo, and real E2E clients
examples/           Executable self-architecture model
test/               Contract tests
docs/assets/        Brand assets and real generated diagram examples

Contributing and license

Contributions are welcome. See CONTRIBUTING.md for setup, validation expectations, and pull request guidance.

Original C4Loom code is MIT licensed. Third-party engines and dependencies retain their own licenses; see THIRD_PARTY_NOTICES.md.

Built on Structurizr, PlantUML, and the MCP TypeScript SDK. Learn more about the C4 model and the official Structurizr MCP.

C4Loom is an independent project, not an official Structurizr product.

Available Tools

4 tools
check_runtimeCheck local enginesA
Read-only

Verify Structurizr and PlantUML hashes. This check does not replace a real generation.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.5/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered structurally. The description adds a useful scope caveat (not a substitute for generation), but omits what is actually compared, what a failure means, and what the output looks like.

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

Conciseness4/5

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

Two short sentences with zero padding, and the scope caveat is placed last where it qualifies the verification claim. 'Hashes' is the only word that could be tightened for precision.

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

Completeness3/5

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

With no output schema, the description carries the burden of explaining what a check result looks like (pass/fail, mismatch detail), which it does not. For a simple diagnostic it is adequate, but an agent cannot predict the response shape.

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

Parameters4/5

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

The tool takes zero parameters, so the baseline is 4; there is nothing for the description to compensate for, and it correctly implies no inputs are needed.

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

Purpose4/5

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

States a specific verb ('Verify') and resources ('Structurizr and PlantUML hashes'), and adds a distinguishing caveat that it does not replace real generation, separating it from generate_c4/render_structurizr. The term 'hashes' is left ambiguous (binary hashes? version fingerprints?), keeping it short of a 5.

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

Usage Guidelines3/5

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

The line 'does not replace a real generation' implies this is a pre-flight/sanity check rather than a substitute for generate_c4, but it never explicitly says when to call it or what to do with the result. Usage is inferable but not stated.

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

generate_c4Generar diagrams C4B

Generate Structurizr DSL/JSON and real C1 context, C2 container, C3 component and C4 code diagrams from an explicit architecture model. Returns transparent SVG/PNG, a viewer and a hashed manifest.

NameRequiredDescriptionDefault
modelYes
levelsNo
projectYesOutput project folder name

TDQS

B3.2/5.0
Behavior3/5

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

Annotations declare readOnlyHint=false and destructiveHint=false, and the description usefully adds that outputs include a viewer and a hashed manifest and that rendering is 'transparent' (traceable). However, it does not say that artifacts are written to a project-named folder, whether existing output is overwritten, or what happens on oversized models — meaningful gaps for a non-idempotent write tool with openWorld=false.

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

Conciseness4/5

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

Two dense sentences, with the generation action and the artifact list front-loaded and no filler. Slightly jargon-heavy but every clause carries information.

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

Completeness3/5

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

Given a deeply nested required 'model' with people, systems, containers, components, codeViews and relationship limits, and no output schema, the description says nothing about model structure or validation constraints. The artifact and return-value side is covered adequately, but the input-side burden is not.

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

Parameters3/5

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

Schema description coverage is only 33% — only 'project' (output folder name) is documented, while the large 'model' object and 'levels' array are not. The description partially compensates by tying the tool to an 'explicit architecture model' and enumerating C1–C4, which the agent can map to the levels enum, but it never explains the model's required shape (focalSystem, systems/containers/components/codeViews).

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

Purpose4/5

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

States a specific verb (generate) and concrete artifacts (Structurizr DSL/JSON, C1–C4 diagrams, SVG/PNG, viewer, hashed manifest), which is far more informative than the title alone. It doesn't distinguish itself from the sibling render_structurizr, which likely also produces diagrams, so the agent can't tell from the description which one to pick.

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

Usage Guidelines2/5

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

The phrase 'from an explicit architecture model' implies the model must be supplied rather than inferred, but there is no explicit when-to-use, no when-not-to-use, and no mention of when render_structurizr would be the better choice. The agent is left to infer the routing decision.

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

read_artifactRead a generated artifactB
Read-only

Return PNG images, editable sources or manifests, restricted to the output root.

NameRequiredDescriptionDefault
pathYes

TDQS

B3.1/5.0
Behavior3/5

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

The annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds useful context about returned content types and an output-root restriction, but says nothing about error behavior, path resolution, or what happens when a path falls outside the root.

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

Conciseness5/5

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

A single compact sentence that front-loads the return types and appends the key scoping constraint. There is no redundant or wasted wording.

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

Completeness3/5

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

For a simple one-parameter read tool with no output schema, the description is adequate about what it returns and its boundary. However, it leaves the crucial path semantics underspecified, which is the main thing an agent needs to invoke it correctly.

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

Parameters2/5

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

Schema coverage is 0% and the sole parameter, path, has no description in the schema. The phrase 'restricted to the output root' hints at path scope, but it does not explain whether the path is relative or absolute, what format is expected, or how extensions map to artifact types.

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

Purpose4/5

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

The description states a specific verb ('Return') and enumerates the resource types returned: PNG images, editable sources, or manifests. It is clearly a read operation and distinguishable from the generator/renderer siblings, though it does not explicitly name alternatives.

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

Usage Guidelines2/5

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

The description gives no explicit when-to-use guidance or alternatives. 'Restricted to the output root' is a scope constraint, not usage advice, so an agent must infer that this tool is for fetching already-generated artifacts.

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

render_structurizrRender Structurizr DSLA

Render real C1-C3 images from self-contained DSL. Use generate_c4 with codeViews for C4. Rejects executable directives and external references.

NameRequiredDescriptionDefault
dslYes
projectYesOutput project folder name

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=false, destructiveHint=false, openWorldHint=false, so the safety profile is partly covered. The description adds real behavioral context beyond that: it rejects executable directives and external references, and requires the DSL be self-contained — which explains the openWorldHint=false claim in practical terms. It does not mention rate limits, failure modes, or where output lands.

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

Conciseness5/5

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

Three short sentences, front-loaded with the core action, then the routing rule, then the constraint. No filler or restatement of the name/title.

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

Completeness4/5

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

No output schema exists, but 'Render real C1-C3 images' plus the 'project' output folder param conveys the return well enough. The main remaining gap is that the DSL dialect/format an agent must write is never characterized beyond what is rejected.

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

Parameters3/5

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

Schema coverage is 50%: 'project' is documented as the output folder name, while 'dsl' has only min/max length. The description partially compensates by constraining what the DSL may contain (no executable directives, no external references, must be self-contained), but gives no syntax, format, or size guidance. Baseline 3 is appropriate given partial schema coverage.

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

Purpose5/5

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

Specific verb+resource: "Render real C1-C3 images from self-contained DSL" tells the agent exactly what is produced and from what input. It also implicitly scopes out C4 rendering, which the next sentence makes explicit, so it is distinguishable from generate_c4.

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

Usage Guidelines4/5

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

Explicitly routes C4 work to the sibling: "Use generate_c4 with codeViews for C4." That is a clear alternative-plus-condition. It does not state when-not to use this tool in any other sense (e.g. size limits, when to prefer read_artifact for existing renders), so it falls short of full 5 coverage.

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

Tool Schema Changelog

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

  1. 4 tool updatesv1.0.0
    • First observedcheck_runtime
    • First observedgenerate_c4
    • First observedread_artifact
    • First observedrender_structurizr

TDQS

A3.5/5.0

Scored across 4 tools

Disambiguation4/5

generate_c4 and render_structurizr both produce C1-C4 diagrams, which is the one real overlap, but the descriptions explicitly delineate them (explicit architecture model vs. self-contained DSL, and render_structurizr points to generate_c4 with codeViews for C4). read_artifact and check_runtime are clearly distinct utility operations.

Naming Consistency5/5

All four tools follow a consistent verb_noun snake_case pattern (generate_c4, render_structurizr, read_artifact, check_runtime). No mixing of conventions or vague standalone verbs.

Tool Count4/5

Four tools is a tight, well-scoped surface for a diagram generation server, with generation, rendering, artifact retrieval, and runtime verification each earning a slot. It is on the lean side but nothing feels redundant.

Completeness3/5

The core loop (generate, render, read output, verify runtime) is covered, but read_artifact requires knowing an exact path and there is no list/gallery tool to discover existing artifacts, nor any cleanup or model-validation operation. Agents hitting an unknown output filename have a dead end.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    A
    maintenance
    Enables AI assistants to generate auto-laid-out, hand-drawn-style Excalidraw diagrams across 25 diagram types from natural-language structure descriptions, with SVG/PNG export and natural-language revision. Runs fully offline without API keys and can persist the described system as a queryable architecture knowledge graph.
    -
  • F
    license
    Not graded
    quality
    A
    maintenance
    Enables AI assistants to turn natural-language descriptions of systems, flows, and data into 25 types of hand-drawn Excalidraw diagrams with automatic layout and architecture-aware styling, then revise them conversationally and export to SVG or PNG. It can also persist a system as a version-controlled, queryable architecture knowledge graph, running fully offline without API keys.
    -
  • F
    license
    Not graded
    quality
    A
    maintenance
    Enables AI coding assistants to turn system architecture into auto-laid-out, editable Excalidraw diagrams across 25 diagram types — architecture, sequence, flowcharts, state machines, ER models, swimlanes, Gantt, and charts — with architecture-aware styling, SVG/PNG export, and natural-language revision. It can also persist the system as a version-controlled, queryable knowledge graph, running fully offline without API keys.
    -