Install
$ agentstack add mcp-chanmeng666-archlang ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ● Filesystem access Used
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ● Dynamic code execution Used
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
> [!IMPORTANT] > ### 🤖 Read this with your AI agent — don't read it by hand. > This repo is written agent-first. Point Claude Code, GitHub Copilot, Cursor, or any agent at it: > "Read the README and AGENTS.md, then help me run / extend this." > Structure + [AGENTS.md](AGENTS.md) are optimized for agent comprehension.
Floor plans as code — like Typst/LaTeX, but for architecture.
Text in, a precise architectural drawing out. Deterministic, zero-dependency, and built so an AI agent can verify its own plan without ever looking at an image.
[](https://www.npmjs.com/package/@chanmeng666/archlang) [](https://github.com/chanmeng666/archlang/actions/workflows/ci.yml) [](https://nodejs.org) [](#-why-it-is-different) [](LICENSE) [](https://github.com/chanmeng666/archlang/stargazers) [](https://github.com/sponsors/ChanMeng666)
▶ Live Playground · 📖 Docs · ⌨ CLI reference · 📦 npm · 🧩 VS Code
👀 See it
Here is a whole program, and below it the actual drawing it compiles to — not a mock-up. Walls join and hatch themselves, the door draws its own swing arc, the window draws its glazing, and the furniture is placed by anchor, never by hand-computed coordinates.
plan "Attached 1BR" {
units mm
grid 100
north up
strip right at (0,0) gap 0 height 4000 { # a row of rooms, laid end to end
room id=r_living size 4000 label "Living" uses living
room id=r_bed size 3000 label "Bedroom" uses bedroom
}
wall id=w_north exterior thickness 200 { (0,0) (7000,0) }
wall id=w_south exterior thickness 200 { (0,4000) (7000,4000) }
wall id=w_west exterior thickness 200 { (0,0) (0,4000) }
wall id=w_east exterior thickness 200 { (7000,0) (7000,4000) }
wall id=w_part partition thickness 100 { (4000,0) (4000,4000) }
door id=d_main on w_south at 2000 width 1000 hinge near start swing into r_living
door id=d_bed on w_part at 2000 width 900 swing into r_bed # opens INTO the bedroom
window on w_west at 50% width 1400 # centred on the wall, by construction
window on w_east at 50% width 1200
furniture sofa in r_living anchor top-left inset 300 size 2000x900 label "Sofa"
furniture bed in r_bed anchor right inset 300 size 1500x2000 label "Bed"
}
↑ arch compile attached.arch — that program, rendered. Nothing above places a wall corner, a door leaf or a sofa by hand.
▶ Click the drawing — it opens the live playground with this exact plan already loaded. Change a number and watch it redraw; the compiler runs in your browser, nothing is sent to a server.
> Why a link and not a live embed? ArchLang does ship an embeddable viewer — but > **GitHub's markdown sanitizer strips `** (it comes back as escaped text, exactly like > ), so no README on GitHub can host one. The embed works everywhere GitHub isn't: > see [Embed a plan anywhere](#embed-a-plan-anywhere). Source: > [examples/attached.arch`](examples/attached.arch).
🌟 Introduction
ArchLang is a small declarative language for floor plans. You declare a plan — walls, rooms, doors, windows, furniture — and the compiler renders a clean, professional SVG (also DXF, PDF, PNG, and a zero-dependency ASCII plan).
Coordinates are integer millimetres, so output is deterministic: the same source always produces byte-identical bytes, and changing one number changes exactly one thing. "Make the bedroom 1 m wider" is a one-number diff — not a re-roll of a raster image that silently redraws the kitchen too.
The compiler is pure TypeScript with zero runtime dependencies and is isomorphic — the same code runs in Node and in the browser, which is why the playground is fully client-side.
> ArchLang is the floor-plan engine behind ArchCanvas, > an AI design agent — but it stands alone and is useful in any app or script.
💡 Why it is different
Most "AI floor plan" tools generate a picture. A picture cannot be checked, diffed, or reasoned about — and neither the model nor you can tell whether the bathroom is actually reachable.
ArchLang generates a program, and then lets you interrogate it as facts:
| | Raster image generation | ArchLang | |---|---|---| | Output | pixels | a .arch program → SVG / DXF / PDF / PNG / TXT | | Edit "widen the bedroom" | re-roll the whole image | change one number | | Same input twice | different image | byte-identical output | | "Is the bath reachable?" | look at it and guess | arch describe --json → access graph | | "Does it match the brief?" | eyeball it | arch validate --intent → exit code | | Wrong syntax | — | errors returned as data, each carrying its own fix |
That last row is the whole design: compile() never throws. It returns diagnostics with byte spans and a machine-applicable fix, which is what makes a tight self-correction loop possible.
🤖 The agent loop
An agent can author a plan, correct itself, and confirm the plan matches the brief without rendering an image at all — which is what makes ArchLang cheap to drive from a text-only model.
flowchart TD
B([Brief]) --> S["arch context — the whole language, one call"]
S --> W["Write .arch"]
W --> C{"arch compile --json"}
C -->|"ok: false"| F["arch fixeach diagnostic carries its own fix"]
F --> C
C -->|"ok: true"| D["arch describe --jsonrooms · areas · adjacency · access graph"]
D --> V{"arch validate --intentdoes it meet the brief?"}
V -->|"no"| G["arch suggestcandidate door / window statements"]
G --> W
V -->|"yes"| O([SVG · DXF · PDF · PNG])
style B fill:#ede7f6,stroke:#6b3ae0,color:#1a1a1a
style O fill:#e8f5e9,stroke:#2e7d32,color:#1a1a1a
style C fill:#fff8e1,stroke:#7a6000,color:#1a1a1a
style V fill:#fff8e1,stroke:#7a6000,color:#1a1a1a
style D fill:#e8f5e9,stroke:#2e7d32,color:#1a1a1a
style F fill:#fdecea,stroke:#b3261e,color:#1a1a1a
style G fill:#fdecea,stroke:#b3261e,color:#1a1a1a
Cold start in one command. arch context prints the entire agent context — language spec, workflow skill, CLI reference and every diagnostic code — as one system-prompt-ready document (the same llms-full.txt the docs site serves).
npx @chanmeng666/archlang context # EVERYTHING: spec + skill + CLI + error catalog
npx @chanmeng666/archlang context --section errors # …or one section of it (the catalog alone: 60 KB → 13 KB)
npx @chanmeng666/archlang spec # just the language, one page (~2k tokens)
npx @chanmeng666/archlang help describe # one command, with worked examples
npx @chanmeng666/archlang compile plan.arch --json # render → { ok, diagnostics, summary }
npx @chanmeng666/archlang fix plan.arch --dry-run # the exact unified diff it would write, applying nothing
npx @chanmeng666/archlang describe plan.arch --json # VERIFY, without an image
npx @chanmeng666/archlang validate plan.arch --strict # the ship gate
Every command takes --json (result on stdout, messages on stderr) with deterministic exit codes (0 ok · 2 user-source error · 1 IO · 3 usage) — and a typo earns that 3: arch lint --jsn exits 3 with did you mean --json? rather than quietly reading --jsn as a filename, and arch comple suggests compile.
One manifest, no drift. The per-command help (arch --help), the flag parser, and the generated CLI reference are all rendered from the same manifest — which is why they cannot advertise a flag a command doesn't take. arch manifest --json is that manifest as data, and arch --help is the cheap way to read one row of it.
Reads are bounded, so a big plan can't flood a context window: describe --select/--room, lint|validate --code/--severity, context --section. Filtering what you read never changes what gates — the exit code always weighs every diagnostic. And because arch fix rewrites your source, it prints the unified diff first and takes --backup.
See [SKILL.md](SKILL.md).
Machine-native artifacts — Plan JSON, a GBNF grammar, an intent schema, and an optional MCP server
| Artifact | Use | |---|---| | /plan.schema.json | Emit structured JSON, compile it with arch compile --from-json | | /archlang.gbnf | Constrain a local model to parseable output | | /intent.schema.json | Write the brief down as a contract; gate on it with validate --intent | | /llms-full.txt | The whole context bundle (arch context) |
MCP server (optional). [@chanmeng666/archlang-mcp](packages/mcp) is a stdio Model Context Protocol shim over the library, listed on the official registry as io.github.ChanMeng666/archlang-mcp:
claude mcp add archlang -- npx -y @chanmeng666/archlang-mcp
Prefer the CLI when your agent has a shell — a CLI costs nothing in the context window until it is called, whereas an MCP tool schema sits there permanently. The server exists so MCP-native hosts can discover ArchLang. The core stays zero-dependency; the SDK lives only in that package ([ADR 0012](docs/adr/0012-mcp-shim-discoverability.md)).
In CI: [.github/actions/arch-render](.github/actions/arch-render) renders every `arch fence in your Markdown to images in one step.
✨ Features
It draws like an architect, not like a plotter
Poché-hatched walls (by material), door swing arcs, window glazing, computed room areas, dimension lines, layers, line weights, a north arrow, a scale bar and a title block. Real fixture symbols for WC, basin, shower, bathtub, sink, counter, fridge and stove — plus dims auto to synthesize dimension strings for you.
It checks architectural soundness, not just syntax
arch lint encodes tacit professional knowledge: a bathroom reachable only through a bedroom, a wet room that isn't fully walled in, a door whose swing hits furniture or another door, a windowless bedroom, an unenterable room, a too-narrow door, a bath/kitchen with no fixtures, and a room whose use was merely inferred from an indirect label (W_ALIAS_MATCH — with a fix that pins the explicit uses). All tunable via the ruleset.
It models how a person actually walks the plan
arch describe runs a clearance-eroded nav grid: per-room walk distance, the narrowest pinch on the way in, and how circuitous the route is — with advisory lint for a too-tight (W_PATH_TOO_NARROW) or roundabout (W_CIRCUITOUS_PATH) walk, and an opt-in arch compile --overlay circulation that draws the routes on top of the plan.
Facts and advice — never an invisible auto-arranger ([ADR 0005](docs/adr/0005-no-invisible-architect.md)). arch repair is the one explicit corrector: it pushes furniture out of walls, doorways and swing arcs, and emits a change log you review.
Errors are data, and many carry a machine-applicable fix
compile() never throws on bad source — it returns diagnostics with byte spans, a catalogued E_*/W_* code, and a fix. Where the edit is mechanical, the diagnostic also carries applicable fixes that arch fix applies for you. --error-svg even turns a plan that won't compile into a self-describing error card an agent can look at.
Parametric, scriptable, and still deterministic
Values, arithmetic, arrays, for/if/while and pure functions — plus relational placement (right-of / below / …) and room strips, resolved by deterministic topological arithmetic, not an optimizer. All of it expands at compile time: no runtime, no clock, no I/O. Optional metric unit suffixes (4m / 40cm / 20mm) fold exactly to millimetres at lex time.
Five output formats · accessible SVG · IDE-grade tooling
SVG, DXF and a TXT ASCII plan with zero dependencies; PDF (vector, selectable text) and PNG (deterministic raster) via optional, lazily-loaded add-ons the default install never pulls. arch compile --accessible stamps the SVG with `/ + role="img"`.
A full LSP (hover, completion, go-to-definition, rename, signature help), an arch fmt formatter, an arch explain catalog, a self-documenting CLI (arch --help, rendered from the manifest, worked examples included), and a VS Code extension.
🚀 Quick start
npx @chanmeng666/archlang new -o plan.arch # scaffold a starter plan
npx @chanmeng666/archlang compile plan.arch -o plan.svg
Or install it:
npm install @chanmeng666/archlang
As a library (zero dependencies, runs in Node and the browser):
import { compile } from "@chanmeng666/archlang";
const { svg, diagnostics } = compile(`
plan "Tiny" {
units mm
grid 50
wall exterior thickness 200 { (0,0) (4000,0) (4000,3000) (0,3000) close }
room id=r at (0,0) size 4000x3000 label "Studio"
door at (2000,3000) width 900 wall exterior hinge left swing in
window at (0,1500) width 1200 wall exterior
}`);
// compile() never throws — errors come back as data, each with a span and a fix.
if (diagnostics.some((d) => d.severity === "error")) console.error(diagnostics);
else writeFileSync("tiny.svg", svg);
Also exported, all pure: describe() (facts), lint() (soundness), validateIntent() + projectSubscores() (does it match the brief?), repair(), applyFixes(), suggestTopology(), renderAscii(), toDxf(), and the LSP core (completion, hover, …).
Develop this repo
npm install # one install bootstraps every workspace
npm run build # build the library + CLI into dist/
npm run check # typecheck + lint + the full test suite
npm run check:drift # every generated artifact must match its source
npm run playground:dev # build the core, then open the playground
🖼️ Gallery
Every one of these is a real, compiled example from [examples/](examples) — click through to the source.
studio The flagship: fitted kitchen & bath,enclosed bath off a central hall.Lint-clean.
two-bed A larger plan: central corridor,multiple rooms and openings.
attached No hand-computed coordinates:strips, on-wall openings, anchors.
Also in [examples/](examples): parametric (a for loop that generates units), themed (a custom
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: ChanMeng666
- Source: ChanMeng666/archlang
- License: MIT
- Homepage: https://archlang.uk/
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.