parti-mcp
Click on "Install 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., "@parti-mcpCreate a whiteprint of a floor plan for a small clinic"
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.
parti-mcp v2
An MCP server that renders architectural floor plans and site plans as SVG in a blueprint aesthetic, following real architectural drawing conventions. Built with precision planar geometry (Clipper WASM + flatten-js).
Office floor plan ( | Residential floor plan ( |
|
|
Both images are rendered directly by the server from the specs in examples/ — walls with cut poché, door swing symbols, room labels with computed areas, an elevator shaft and stair with UP/DN, dimensions, a title block, north arrow, and scale bar.
Features
Precision geometry engine: Uses Clipper (js-angusj-clipper) for robust planar geometry operations with integer-precision scaling
Analytical primitives: flatten-js for centroids, point-along-path, perpendiculars, and arc geometry
Architectural rendering: Proper wall junctions (offset→union→cut→stroke), door/window symbols, room labels with area calculations
Vertical circulation & structure: Stairs (tread lines + UP/DN arrow + break line), ladders, elevators (shaft symbol), columns/piers with material poché
Wall vocabulary: Straight or circular-arc (curved) walls, full-height or low (half/pony/knee) walls, and mixed materials on a single floor (rendered per material group)
Legible labels: Room and site labels render on a background "safe area" halo so busy hatching never bleeds through the text
Multi-theme output: Blueprint (dark) and Whiteprint (light) themes with theme-aware text contrast
Multi-scale support: Automatic scaling from paper millimeters to model units (1:100, 1:50, 1:200, etc.)
Multi-floor plans: Render each floor separately or batch process buildings
Site and city plans: Buildings, parcels, roads, green spaces, water features, barriers, trees, and paved areas
Related MCP server: Atelier
Architecture
Core Geometry Pipeline
Input: FloorPlanSpec or SiteSpec (Zod-validated schemas)
Geometry Processing:
Wall/road polylines are offset to solid bands (Clipper)
Overlapping bands are unioned (Clipper with NonZero fill rule)
Junctions are cleaned via offset→union→cut workflow
Interior polygons (rooms/parcels) are extracted
Rendering:
Walls/roads/outlines rendered as stroked paths (no fill)
Rooms/buildings rendered as filled polygons with hatch patterns
Openings (doors/windows) cut from walls or drawn as symbols
Text labels positioned at centroids with automatic contrast detection
Title blocks, scale bars, and north arrows added per AIA conventions
Output: SVG with embedded patterns, markers, and defs
Key Files
src/geometry/clipper.ts: Clipper WASM wrapper, offset, union, difference operations
src/geometry/primitives.ts: flatten-js wrappers for centroids, perpendiculars, point-along-path, polygon area
src/geometry/scale.ts: paper-mm ↔ model-unit conversion, dimension text formatting, scale-bar tick stops
src/render/theme.ts: blueprint/whiteprint palettes, lineweight/linetype resolution, contrast-aware text color
src/render/titleblock.ts: Title block generation with scaled text and backgrounds
src/render/symbols.ts: Door swing, window glazing, grid bubbles, dimension strings, scale bars, north arrows
src/render/sheet.ts: Sheet assembly — border, title block, north arrow, scale bar around the drawing content
src/tools/renderFloorPlan.ts: Floor plan rendering pipeline
src/tools/renderSitePlan.ts: Site plan rendering pipeline
Getting Started
Use it as an MCP server
parti-mcp is a stdio MCP server: an MCP client (Kiro, Claude Desktop, etc.) launches it and calls its tools. You don't run it by hand — you point your client's config at a command that starts it.
Run directly from GitHub (no clone, no install step):
{
"mcpServers": {
"parti-mcp": {
"command": "npx",
"args": ["-y", "github:Hbler/parti-mcp"]
}
}
}Or, once published to npm:
{
"mcpServers": {
"parti-mcp": {
"command": "npx",
"args": ["-y", "parti-mcp"]
}
}
}Either way the client spawns the server, which exposes three tools: render_floor_plan, render_site_plan, and ping. The server advertises the full JSON Schema for each spec plus a usage brief in its MCP initialize response, so the calling model knows every field.
The package builds itself on install (a
preparestep compiles TypeScript todist/), and the compiled entry runs on plain Node — no globaltsxneeded on the consumer's machine.
Develop from source
git clone https://github.com/Hbler/parti-mcp
cd parti-mcp
npm install # also builds dist/ via the prepare step
npm start # run the server over stdio from TypeScript source (tsx)
npm run build # type-check and emit dist/To point an MCP client at your working copy instead of the published package:
{
"mcpServers": {
"parti-mcp": {
"command": "npx",
"args": ["tsx", "/absolute/path/to/parti-mcp/src/index.ts"]
}
}
}Running Tests
npm testCovers:
Geometry operations (clipping, offsetting, unions)
Schema validation
Rendering pipeline
Integration tests with real examples
Regression tests for known bugs (junction seams, text sizing, enclosed-room poché)
Rendering examples without a client
To render the bundled examples directly (writes SVGs to smoke-output/):
node --import=tsx scripts/smoke-test.mjsOr call a tool handler from your own script. Import the .ts sources with tsx when running from a source checkout, or the built dist/*.js when running against a compiled install:
import { initializeClipper } from "./src/geometry/clipper.ts";
import { handleRenderFloorPlan } from "./src/tools/renderFloorPlan.ts";
import fs from "node:fs";
await initializeClipper(); // required once before any render
const spec = JSON.parse(fs.readFileSync("examples/house.json", "utf-8"));
const result = await handleRenderFloorPlan({ spec });
console.log(result.content[0].text); // SVG output (one entry per floor)Example Specifications
Floor Plan (house.json)
Single-floor residential plan:
15m × 10m footprint
2 rooms (living room, kitchen)
Interior partition wall
Exterior doors/windows
Dimension annotations
{
"unit": "m",
"scale": "1:50",
"theme": "blueprint",
"titleBlock": { /* ... */ },
"floors": [
{
"id": "ground-floor",
"level": 0,
"outline": [[0, 0], [15, 0], [15, 10], [0, 10]],
"walls": [ /* paths with thickness */ ],
"rooms": [ /* polygons with labels */ ],
"openings": [ /* doors and windows */ ],
"dimensions": [ /* annotation lines */ ]
}
]
}Multi-Floor (two-floor.json)
Two-story residential:
Ground floor: Living Room, Kitchen/Dining, Entry Hall, WC
First floor: bedrooms, bathroom, landing
A stacked stair (UP on the ground floor, DN on the first) positioned clear of door swings
Columns placed on the structural grid
Interior partitions on both levels
Detailed House (house-detailed.json)
Exercises the fuller vocabulary: a low (knee) wall, stairs running to an upper level, and a loft-access ladder.
Curved Wall (curved-wall.json)
Minimal demo of a curved wall (a shallow bay window authored as a two-point wall with curve) and a round column.
Office Building — Level 2 (office.json)
Commercial floor plate: an elevator + stair core (single lobby, one corridor door), a central corridor, two restrooms opening onto the corridor, open-plan and cellular offices, and columns on grid.
City / Figure-Ground (city.json)
Urban site plan at 1:500: labeled building footprints, a street grid, and a park plaza.
Whiteprint (house-whiteprint.json)
The bungalow rendered in the light (whiteprint) theme, with one highlighted room demonstrating per-element style.fill.
Site Plan (site-plan.json)
Residential site with:
Main building footprint
Property parcel boundary
Street frontage
Driveway (asphalt)
Sidewalk (concrete)
Pool (water feature)
Landscaping (lawn, garden)
Property fence
Site trees with species
{
"unit": "m",
"scale": "1:100",
"buildings": [ /* footprints with labels */ ],
"roads": [ /* paths with width */ ],
"pavedAreas": [ /* polygons with surface type */ ],
"greenSpaces": [ /* polygons with landscape type */ ],
"water": [ /* polygons with water type */ ],
"barriers": [ /* paths with barrier type */ ],
"trees": [ /* positions with radius and species */ ]
}CLI Tools
renderFloorPlan
Renders architectural floor plans with proper junction handling and legend.
export async function handleRenderFloorPlan(input: {
spec: FloorPlanSpec;
outputPath?: string;
}): Promise<ToolResult>;Input Schema (FloorPlanSpec):
unit: "m" | "ft" | "mm"scale: "1:50" | "1:100" | "1:200" (etc.)theme: "blueprint" | "whiteprint"titleBlock: Optional title block metadatafloors[]: Array of floor specs, each with:outline: Boundary polygonwalls[]: Wall centerlines withthicknessand optionalmaterial(mixed materials on one floor render per group). OptionalheightClass:"full"(default, solid cut poché) or"low"(half/pony/knee wall or railing below the cut plane → dashed outline, no fill). A wall may curve: give a two-pointpathpluscurve: { radius, clockwise }and the server tessellates a circular arc that unions/cuts like a straight wall.rooms[]: Room polygons with type and optional custom fill (labels render on a legibility halo)openings[]: Doors/windows referencing a wall bywallIdatpositionAlongWallin [0,1]; doors needhinge(start|end) +swingSide(left|right)stairs[]: Straight-run stairs —footprint,run[bottom, top] travel centerline,treadscount,direction(up|down)ladders[]:path[start, end] +width(rails + rungs)elevators[]:footprint(shaft rectangle) + optionallabel(X-in-box shaft with inset car)columns[]:position,shape(square|rectangular|round),sizeorwidth+depth, optionalmaterial(poché footprint — place on grid intersections)dimensions[]: Annotation lines with textgrid: Optional structural grid (labeled bubbles)
Output: SVG at outputPath or returned as text
renderSitePlan
Renders site plans with buildings, roads, landscape, and utilities.
export async function handleRenderSitePlan(input: {
spec: SiteSpec;
outputPath?: string;
}): Promise<ToolResult>;Input Schema (SiteSpec):
buildings[]: Building footprints with labelsroads[]: Road polylines with widthpavedAreas[]: Paved polygons (driveways, parking, sidewalks)greenSpaces[]: Landscape polygons (lawn, garden, trees)water[]: Water features (pools, ponds)barriers[]: Fences, walls, hedgestrees[]: Individual tree positions with radius and species
Scale and Units
All coordinates are in model units (meters, feet, mm depending on spec).
Scale conversion is automatic:
Input scale string (e.g., "1:100") is parsed
SVG font sizes and line widths are scaled appropriately
At 1:100 with meters, 0.1 model units = 1cm on paper
Text is rendered proportional to drawing size (0.5–3% of bbox height)
Unit handling:
All internal calculations use model units
Title blocks, scale bars adapt to unit and scale
Theme System
Blueprint (default)
Background: Prussian blue (
#0B3D91)Ink: Pale cyan (
#E0F2FF)Poché fill: Darker blue (
#1A4BA8)
Whiteprint (opt-in)
Background: White (
#FFFFFF)Ink: Black (
#000000)Poché fill: Light gray (
#D3D3D3)
Per-element fill and label contrast
Any drawable entity may set style.fill to highlight it in a specific color, regardless of theme. Room and site labels render on a background "safe area" halo (a card behind the text) so that dense floor/site hatching never renders through the label. On top of the halo, getContrastingTextColor picks whichever of the theme's ink or background color has the greater luminance distance from the room's actual fill, so a label stays legible whether the room uses the theme default or a custom highlight color, in either theme.
Technical Details
Geometry Operations
Offsetting Walls to Bands:
Path (centerline) + thickness → Solid band polygonJunction Handling (offset→union→cut→stroke), the core fix that makes connected walls/roads read as one drawing instead of overlapping outlines:
1. Offset every wall/road centerline in a floor/site to its own solid band (OpenButt end type)
2. Union all bands into one merged polygon (NonZero fill rule — EvenOdd would
treat the genuinely-overlapping area at a junction as a hole and split
the result back into separate pieces)
3. Difference the door/window opening cutters from that merged polygon
4. Stroke the single resulting boundary once — never per-wallWalls are grouped by material and each group runs through this pipeline independently, so a floor can mix materials (each hatched on its own). Each group's cut poché is emitted as a single fill-rule="evenodd" path: when interior walls form a connected loop, the union returns the enclosed room void as a separate opposite-winding subpath, and even-odd makes that void a hole rather than a filled polygon — otherwise the room interior would be flooded with the wall hatch.
Rooms are author-supplied, not derived. A Room.polygon is authored directly in the spec to the room's interior wall face — it is not extracted or computed from the wall geometry. This keeps the computed area (getPolygonArea) honest as usable floor area, and means room fill always meets wall poché with no gap as long as the spec author places the room polygon at the wall's inner face. Label position is the room polygon's centroid (getCentroid).
Text Rendering
All text sizing is computed as:
fontSize (model units) = textSizeInPaperMm * modelPerPaperMm(scale, unit)
modelPerPaperMm = scaleDenominator / mmPerUnitFor scale "1:100" with unit "m" (1 m = 1000 mm):
modelPerPaperMm = 100 / 1000 = 0.1
1.5mm text → 1.5 * 0.1 = 0.15 model units (15 cm — reads correctly on a drawing sized in metres at 1:100)
This same conversion drives every line weight, tick size, and bubble radius — nothing is a hardcoded pixel/model-unit constant, so output reads correctly whether the spec is a metre-scale floor plan or a much larger site plan.
Text is rendered with font-family="monospace" for deterministic sizing.
Patterns and Hatches
Hatches are defined as SVG <pattern> elements (patternUnits="userSpaceOnUse", so density stays scale-correct and continuous across adjacent shapes) in <defs> and referenced via fill="url(#hatch-type)":
hatch-brick: 45° diagonal lineshatch-masonry: 45° diagonal lines, coarser than brickhatch-concrete: Stipple/dot patternhatch-insulation: Batting patternhatch-lawn: Scattered circles for grasshatch-pavers: Grid pattern for paved areashatch-earth: Dense 45° lines for soil
Known Limitations
All polylines are treated as open paths; closed loops require explicit endpoint
Text is positioned at geometric center; complex labels may benefit from manual adjustment
Curved walls are supported as circular arcs only (a two-point path plus
curve: { radius, clockwise }, tessellated before offsetting); non-circular curves (splines, ellipses) are not supportedPlans are a single 2D horizontal cut — there is no continuous vertical model. Furniture/fixtures and MEP are out of scope
High-precision geometry relies on integer arithmetic; very large drawings may lose precision
Contributing
All code follows TypeScript strict mode. Changes must:
Pass
npm run build(TypeScript check)Pass
npm test(full test suite)Update relevant tests if schemas or rendering change
For new examples, render to
output/examples/and visually verify (e.g. rasterize withqlmanage -t -s 1600 -o <dir> output/examples/*.svg)
License
MIT — see LICENSE.
Version History
v2 is a full rebuild of an earlier Turf.js-based prototype: a different geometry engine (Clipper + flatten-js, replacing Turf's geospatial/spherical math, which was the root cause of a geometry bug at wall/road junctions) and a renderer that follows real architectural drawing conventions (blueprint aesthetic, real units + named scale, line-weight hierarchy, poché/material hatching, dimensioning, structural grid, title block, north arrow, scale bar) rather than a generic vector diagram. See docs/REASONS-CANVAS.md for the full design history.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables to create, compose, and export SVG documents programmatically using the svgwrite library through tool calls. Supports shapes, groups, gradients, and pattern generators.
- AlicenseNot gradedqualityAmaintenanceConverts spoken descriptions into standards-compliant floor plans and furnished 3D models, enabling real-time collaborative editing through a live browser editor with Claude AI.4Apache 2.0
- AlicenseNot gradedqualityCmaintenanceConverts LaTeX math expressions to SVG. Enables AI assistants to render mathematical formulas as scalable vector graphics.37MIT
- FlicenseAqualityBmaintenanceAn MCP server that generates standalone SVG architecture diagrams from text descriptions, running entirely on your machine with no dependencies or network access.8
Related MCP Connectors
DXF and PDF/X-4 for AI agents: structured facts, PNG renders, an interactive in-chat viewer.
Generate styled PNG/SVG map images of any location with 11 customizable color themes.
Generate cloud architecture diagrams, flowcharts, and sequence diagrams.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Hbler/parti-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server

