Skip to main content

koyu-mcp

koyu-mcp is the MCP server shipped inside koyu. It is the surface through which an LLM agent reads a building, edits it, and confirms what it did — returning the same derivations the koyu command gives you, as JSON.

What it is

Executablekoyu-mcp — installed alongside koyu by @kensnzk/koyu
Transportstdio. Line-delimited JSON in on stdin, line-delimited JSON out on stdout
ProtocolJSON-RPC 2.0 — written by hand. No MCP SDK is used
Runtime dependenciesNone
Environment variables, authentication, networkNone
RequiresNode 22 or later
Tools12

The version serverInfo announces is the implementation's (0.16.0), not the notation's (koyu 1.0). The two versions move independently.

It is stateless

All 12 tools take a required file argument. file is the path of the entry .muro; for a building split into layers with import, pass the base layer's file.

One call goes: resolve the path, read the entry, follow the imports, compose, answer the question, forget. There is no session, no open document, no cache, no undo stack. Call it twice with the same arguments and it composes twice.

So the server never holds a version of the building that the disk does not have. The original is the filesystem, and the history is git's.

Re-composing is cheap. The bundled nine-layer tower takes about 6 ms; the largest bundled example (11 layers, 1,808 spaces, 141,448.56 m² of floor) stays under 100 ms.

Registering it

claude mcp add koyu -- npx -p @kensnzk/koyu koyu-mcp

Per-client instructions, and how to register a development build (node /path/to/koyu/dist/mcp.js), are on Registering it with a client.

Pass the entry as an absolute path. A relative path is resolved against the server process's working directory, and which directory a client starts the server in is up to that client. Get it wrong and you get Cannot read file:.

The standard loop

Shape the agent's work like git's.

model_summary  →  layers  →  write_layer  →  check ──errors──→ fix, write_layer again

                                               └──green──→ doors / light / site confirm the consequences
  1. Grasp the building with model_summary. Layer composition, levels, zones, assets, areas and the check counts come back in one call, which tells you which file to read next.
  2. Read the original with layers. The full text of every composed layer comes back.
  3. Write with write_layer. A whole-file replacement, not a diff. The response carries the check result from immediately after the write, so editing and verifying take one round trip.
  4. check is the gatekeeper. If errors come back, fix them and write again.
  5. Confirm the consequences with doors / light / site. Move a partition and circulation and daylight change; change an area and coverage changes. check was not looking at any of that.

The 12 tools

ToolArgumentsWhat comes back
model_summaryfileName, unit, layers, levels, zones, assets, areas, check counts
layersfile{file, source} for every composed layer
spacesfile, level?The spaces — path, type, name, level, area, semi-outdoor flag, originating layer
canonical_jsonfileThe canonical JSON (one composed model)
write_layerfile, layer, contentReplaces a layer wholesale. Returns written plus the check from right after
new_uidsfile, count?Fresh persistent identity tokens
checkfileStructural consistency — ok, errors/warnings, diagnostics
validatefileArchitectural verdicts — findings, violations, cautions
doorsfile, from, toThe fewest-doors route, or {unreachable: true}
lightfileFloor area and effective window area for every space written daylight:1
sitefileSite area, road frontage, coverage ratio, floor-area ratio
plan_svgfile, levelThe plan SVG for that level, as a string

? marks an optional argument. The JSON-RPC surface — what initialize announces, the shape of a tools/call result, how errors come back — is on The protocol.

Do not conflate the two greens

A green check and a usable building are different things. The default between touching spaces is a wall, so a two-storey building that declares no door at all stays green in check while being perfectly sealed. check says only that what is written holds together as data; architectural soundness is what validate says, separately.

They differ down to the type. check's diagnostics carry {code, severity}; validate's findings carry {rule, level}. The spellings differ and the two arrays cannot be concatenated. Do not claim a building works because check is green.

Commit before you let it write

write_layer replaces a file wholesale and has no undo. The server stores not one previous version. Branching, review and rollback are all git's job.

Commit your .muro files before starting work that lets an agent write. The full blast radius is on Writing — write_layer / new_uids.

See also