C4Loom
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@C4LoomGenerate C1–C4 diagrams for my e-commerce system with web, API, and database containers."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
C4Loom
Weave architecture into diagrams.
A local-first MCP server that generates real C1-C4 diagrams, not just diagram text.
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
Diagram gallery
These diagrams are generated from the executable C4Loom self-architecture example. They describe this tool, not a fictional application.
C1 · System context | C2 · Containers |
|
|
C3 · MCP server components

C4 · Architecture compiler modules

Quick start
Prerequisites
Node.js 22+ and npm.
Java 21+, available as
javaor configured throughC4_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 demoOn 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/projectThis 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 |
|
| Real C1-C4 diagrams, editable sources, viewer, and manifest. |
|
| Real C1-C3 images from an existing workspace. |
| Absolute artifact | A PNG image or supported text artifact inside the output root. |
| 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 |
| Workspace identity and purpose. |
| Identifier of the system to detail. |
| People with |
| Systems and their containers. |
| Components within each container. |
| Explicit |
| Code views attached to components in the focal system. |
| Classes, interfaces, modules, procedures, or records. |
| 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 assetsEach 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
Validate the explicit architecture contract and element references.
Compile Structurizr DSL and code-view PlantUML.
Render C4 locally with PlantUML's Smetana layout engine.
Parse and export the complete workspace with the official Structurizr engine.
Render C1-C3 using the native Structurizr browser export API in Chromium.
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 |
|
|
|
|
|
|
| Playwright-managed Chromium; optional executable override. |
| Optional externally managed Node package directory. |
|
|
|
|
|
|
| Unset; optional official MCP endpoint. |
| Unset; set to |
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 |
| Official Structurizr distribution. |
PlantUML MIT |
| Maven Central |
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:e2eThe 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 |
Java launch/version error | Install Java 21+ and check |
Chromium executable missing | Run |
Browser libraries missing on Linux | Run |
Missing code view | Declare |
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 examplesContributing 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 toolscheck_runtimeCheck local enginesARead-only
Verify Structurizr and PlantUML hashes. This check does not replace a real generation.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| model | Yes | ||
| levels | No | ||
| project | Yes | Output project folder name |
TDQS
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.
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.
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.
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.
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.
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 artifactBRead-only
Return PNG images, editable sources or manifests, restricted to the output root.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| dsl | Yes | ||
| project | Yes | Output project folder name |
TDQS
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.
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.
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.
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.
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.
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.
4 tool updates
v1.0.0- First observed
check_runtime - First observed
generate_c4 - First observed
read_artifact - First observed
render_structurizr
TDQS
Scored across 4 tools
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.
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.
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.
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
Related MCP Connectors
Create and edit architecture diagrams from your AI agent; get an SVG and a live editable canvas.
Design domain models and generate deterministic multi-stack code, driven by your coding agent.
Generate cloud architecture diagrams, flowcharts, and sequence diagrams.
Polished system design diagrams (SVG/PNG) from a tiny YAML spec, ~18x fewer tokens than raw SVG.
Related MCP Servers
- FlicenseNot gradedqualityAmaintenanceEnables 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.-
- FlicenseNot gradedqualityAmaintenanceEnables 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.-
- FlicenseNot gradedqualityAmaintenanceEnables 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.-
- FlicenseNot gradedqualityAmaintenanceEnables users to turn architecture into a queryable knowledge graph and produce editable, hand-drawn, auto-laid-out diagrams across 25 types, with natural-language revisions and SVG/PNG export. It runs fully offline without API keys.-

