Skip to main content
Glama

isodia-mcp

Isometric architecture diagrams that agents and people draw together: an MCP server, a browser canvas, revision history and share links, over one model.

An agent builds a diagram region by region in an open browser canvas; a person zooms in, drags an item and searches the icons; the agent adds a connector, a second view and a share link; the history lists every step; the shared page shows the result read-only

Unedited apart from the caption and pointer. The agent is a real MCP client calling build_diagram, edit_diagram, manage_views and share_project while the canvas is open; the person zooms in, drags an item, searches the icons and switches view. Every step lands in the history, and the last scene is the read-only shared page. Recorded by scripts/record-demo.ts.

The same diagram as the renderer exports it, from one build_diagram call (examples/storefront.ts); the layout, routing and artwork are isodia's:

A made-up online store drawn by isodia: 20 systems in six regions

Everything that draws or changes a diagram is this project's own: the model rules, the layout engine, the renderer, the canvas and the icon set. Diagrams are stored in the open Isoflow model format, so files move between isodia and other tools that read it; isodia includes no Isoflow code and is not affiliated with it.

The canvas is one surface; the product is the model, the history and the agent interface. Agents create, lay out, edit and render diagrams through MCP, and people get the same diagrams in a browser with autosave, revision history and read-only share links. A person's edit on the canvas and an agent's edit over MCP are the same operations, and the canvas is drawn by the same renderer that exports the pictures.

Quick start

bun install
bun start          # API + MCP over HTTP on :4400
bun run dev:web    # web app on :4401, proxying /api and /mcp to :4400

Open http://localhost:4401. Create a project, or let an agent do it (below).

For a single-origin deployment, build the web app once and let the API serve it:

bun run build      # writes dist/
bun start          # serves the app and the API together

The build is a normal deploy step, so run it in CI or at release time.

Docker

docker build -t isodia-mcp .
docker run -p 4400:4400 -v isodia-data:/data \
  -e ISODIA_TOKEN="$(openssl rand -hex 32)" \
  -e ISODIA_URL=https://diagrams.example.com isodia-mcp

ISODIA_URL is the address clients reach, and it is what the Connect-agent panel and share links print — set it to the public URL, not localhost. Projects live in /data/isodia.db, so mount a volume or they are lost with the container; the image runs as the unprivileged bun user and the volume is created with the right ownership. The image listens on all interfaces (HOST=0.0.0.0), so it refuses to start without ISODIA_TOKEN, the bearer token the API and the HTTP MCP endpoint then require.

The base image must be glibc, because @resvg/resvg-js ships a prebuilt native binary and does not run on musl; the provided image is Debian-based, and most of its size is the Bun base. The runtime stage installs production dependencies only, and the build fails unless that install can check a model and render a picture.

Related MCP server: Draft

Connect an agent

The built-in panel (Agent on a project page) prints both configurations.

stdio, on the same machine — nothing to host:

{
  "mcpServers": {
    "isodia": {
      "command": "bun",
      "args": ["/absolute/path/to/isodia-mcp/src/server/mcp-stdio.ts"]
    }
  }
}

HTTP, when the server is reachable over the network:

{ "mcpServers": { "isodia": { "type": "http", "url": "http://localhost:4400/mcp" } } }

Both processes share one SQLite file (ISODIA_DB), so an agent over stdio and the web app see the same projects. The default path is resolved from the repository, not the working directory, so both find the same file however they are started.

Some MCP clients start stdio servers with a filtered environment. If you change ISODIA_DB, set it explicitly in the server's env block as well, or the server falls back to the default and appears empty.

Tools

Tool

Purpose

list_projects, create_project, delete_project

Project lifecycle

get_diagram

Read a view: items with tiles, connectors, regions, text

build_diagram

Replace a view with nodes/edges/groups, laid out automatically

edit_diagram

Atomic batch of edits: add, place, update, move, remove, connect, regions (draw, retitle, move with contents), text, auto_layout

manage_views

Create, rename, copy or delete views

search_icons

Find icon ids in the bundled set by keyword (postgres finds database)

render_diagram

PNG image or SVG source of a view

list_revisions, restore_revision, save_checkpoint

History

share_project

Create, list and revoke read-only share links

export_project, import_project

Model JSON (Isoflow format) in and out

render_diagram returning a real image is what lets an agent check its own layout instead of guessing.

Revision history keeps the newest 100 revisions, the original import and any revision named with save_checkpoint; older unnamed autosaves are pruned so storage stays bounded. Each revision is a full model snapshot, so name the ones worth keeping.

bun scripts/mcp-demo.ts                    # every tool over stdio, with a real MCP client
bun scripts/mcp-http-demo.ts               # the same over the HTTP endpoint
bun scripts/registration-check.ts          # handshake against the stdio entry point

examples/busy.ts is a worked example against a real repository: it builds five views (deployment, message path, durable work, trust boundaries, repository map) through the MCP server, saves a checkpoint and writes an SVG and a 1600 px PNG per view plus the model JSON. --png-only skips the SVGs, which embed the icon artwork and are large. It runs against a live server and recreates its own project each time:

PORT=4410 ISODIA_DB=/tmp/busy-docs.db bun src/server/index.ts &
bun examples/busy.ts --url http://127.0.0.1:4410 --out /tmp/busy-diagrams

Model and layout

A project is one model: a shared list of items (name, icon, description) plus one or more views that place those items on a tile grid. So "the same systems, for a different audience" is a second view, not a second diagram.

build_diagram lays out a graph: edges flow from the upper left toward the lower right, each group becomes a titled coloured region sized to hold its title, and regions never overlap. A region's title sits on its own row inside its upper edge, so it never collides with the icon artwork or labels of the items below. edit_diagram changes the layout surgically and leaves everything else where it is.

Connector labels are placed on the route, not on the nearest tile: the renderer picks a free tile with the most clearance from every item, closest to the middle of the route. A label on an item's tile would vanish behind the icon, because items paint last, and two labels on one tile would hide each other.

Every change is checked against the model schema (src/core/schema.ts) before it is stored: whole-number tiles, unique ids, and every reference to an item, icon, colour or anchor resolved. A model that cannot be drawn cannot enter the database.

Icons

The bundled icons are generic nouns (server, database, queue, user, gateway…) drawn as uncoloured isometric paper models and generated from code in src/core/iconset/. There are no vendor logos: name the product in the item's label. Search answers to the names people use, so postgres, s3 or lambda find the right noun. A model can carry its own icons in icons (any image as a data URI); they travel with the model and win over a bundled icon of the same id. bun scripts/icon-sheet.ts --out sheet.png renders the whole set.

The canvas

Tools are words in one bar: Select (click, drag to move, drag empty space to pan), Connect (click one item, then another), Region (drag across tiles), Text (click a tile), then Add item, Undo, Redo and Tidy (lay the view out again). The selection's properties appear beside it and are shown on the canvas as you type. Dragging a region moves what stands in it; a selected region resizes by its corner handles. The wheel pans, Ctrl or Cmd with the wheel zooms. Keys: V C R T I, Del, Esc, Ctrl+Z, Ctrl+Shift+Z. A share page is the same canvas, read-only: clicking an item shows its name and notes.

Design

One look runs through the app and the pictures it renders: warm paper, one ink, pale washes for regions, neutral lines, IBM Plex, and a single orange accent kept for what an agent did and where you are. DESIGN.md has the tokens, the rules for drawing a diagram, the reasons, and the known debts. The values live in src/core/theme.ts and web/src/styles.css.

Colours are stored in each model, so a project made before a palette change, or imported from another tool, keeps the colours it was drawn with.

Storage

One SQLite file (WAL, so several processes can share it):

  • projects — the current model and a revision counter

  • revisions — every saved state, with what made it (editor, mcp, api, import, restore)

  • share_links — tokens granting read access to one project

Editor autosaves collapse into one revision per two-minute burst, so a burst of keystrokes does not bury the history. Agent edits and checkpoints always stand alone.

Optimistic concurrency: the editor saves against the revision it loaded. If an agent changed the project meanwhile, the save is refused (409) and the browser shows the newer revision.

Configuration

Variable

Default

Meaning

HOST

127.0.0.1

Interface to listen on. Anything but localhost requires ISODIA_TOKEN

PORT

4400

HTTP port

ISODIA_DB

data/isodia.db

SQLite file shared by all processes

ISODIA_URL

http://localhost:$PORT

Public base URL used in links and MCP output

ISODIA_TOKEN

unset

When set, the API, /mcp and the app require Authorization: Bearer <token>

Share links are always public: the token is the credential. That is what makes a shared diagram openable by a client without an account.

Security

  • Local only by default. The server listens on 127.0.0.1 with no authentication, so only programs on this machine can read, change and delete projects through the API and /mcp.

  • Serving other machines needs a token. Setting HOST to anything but localhost makes the server refuse to start unless ISODIA_TOKEN is set. The Docker image sets HOST=0.0.0.0.

  • Custom icons are inline pictures. An icon url must be a data:image/… URL; file paths and remote addresses are rejected, on import too.

  • A share link is a credential. Anyone holding it can read that project until you revoke it.

  • Diagram text is user content and is only ever shown as text. Names, labels and notes are escaped by the renderer and reduced to plain text by the canvas; no HTML from a model is inserted into the page. A model's own icons are images shown through SVG <image>, which does not run scripts.

  • The stdio MCP server has the same access as the user who starts it; it does not check the token.

Report vulnerabilities privately through the repository's security advisories, not public issues.

HTTP API

GET/POST /api/projects, GET/DELETE /api/projects/:id, PUT /api/projects/:id/model, POST /api/projects/:id/build, POST /api/projects/:id/operations, GET /api/projects/:id/render, GET /api/projects/:id/export, GET /api/projects/:id/revisions, POST /api/projects/:id/revisions/:n/restore, POST /api/projects/:id/checkpoints, GET/POST /api/projects/:id/shares, DELETE /api/shares/:token, GET /api/icons, POST /mcp, and the public GET /api/shared/:token.

Tests

bun test                                      # unit and integration suites
bun scripts/seed-demo.ts                       # rebuild the two demo projects the browser check drives
export CHROME_PATH=/usr/bin/chromium           # any Chrome or Chromium binary
bun scripts/browser-check.ts                  # browser smoke test; needs both dev servers
bun scripts/mcp-demo.ts                       # MCP over stdio, end to end
bun scripts/mcp-http-demo.ts                  # MCP over HTTP, end to end

browser-check.ts expects the payments-platform and acme-retail-platform demo projects, so run seed-demo.ts first on a fresh database. Both scripts read API_URL/WEB_URL and default to the dev ports; the browser check also needs CHROME_PATH. It drives every canvas tool on a scratch project, checks each edit against what the server stored, and exits non-zero when a step fails or when a page logs an error, a failed request or an uncaught exception. The only complaint it expects, and discounts, is the 404 for the share link it revokes.

Both serving modes are covered. Point both variables at a single-origin server to check the production path, where no proxy sits in front of /api or /mcp:

bun run build
PORT=4500 ISODIA_URL=http://127.0.0.1:4500 bun src/server/index.ts &
API_URL=http://127.0.0.1:4500 bun scripts/seed-demo.ts
WEB_URL=http://127.0.0.1:4500 API_URL=http://127.0.0.1:4500 bun scripts/browser-check.ts

CI owns the full build and test gates; bun run build is a deploy step, not part of a code change.

Notes

  • Stored models keep only their own icons. Bundled icons are resolved by id when a model is drawn, and embedded on export so the file is complete on its own.

  • Import and export run through the server, so history and validation always apply.

  • A model made elsewhere that names an icon it does not carry, and that the bundled set does not have (a vendor icon from another tool's pack, for example), is refused with the icon's name. Embed the icon in the file's icons, or change the item to a bundled noun.

Licence

MIT, see LICENSE: the code and the icon artwork. The dependencies keep their own licences, all permissive or weak-copyleft and none modified; NOTICE.md lists them, and should travel with anything you ship or host.

Tool Schema Changelog

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

Loading tool schema changelog…

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      C
      maintenance
      Generates editable .drawio architecture diagrams from descriptions or reference images, with secure asset resolution, validation, and revision-based approvals.
      11
      71 npm
      1
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables agents to draw on a self-hosted canvas by creating and editing frames, text, shapes, images, and SVGs with auto-layout, then inspecting, exporting, and sharing the results. Also supports live viewing of agent edits, pinned comments, screenshots, and revision history so people and agents can collaborate on boards.
      747 npm
      1
      MIT
    • F
      license
      Not graded
      quality
      A
      maintenance
      Enables AI assistants to turn architecture and data into living, queryable knowledge graphs and generate 25 types of hand-drawn, auto-laid-out diagrams that remain editable. It supports natural-language revisions, architecture-aware styling, SVG/PNG export, and fully offline use without API keys.
      -
    • 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.
      -