Releases: vicmaster/framesmith
v1.0.0 — framesmith
First public release. npx framesmith — an open-source MCP server that gives your AI coding agent a visual design canvas: sketch the UI, review it in a browser, agree on the design before any framework code gets written.
Formerly canvas-mcp — renamed to framesmith for v1.0.
Headline: your designs live in your repo
Canvases persist as open JSON in a .framesmith/ directory, checked in alongside your code — committable, diffable in code review, and self-contained on clone. The repo is the source of truth; no proprietary, encrypted store. Bind a workspace with canvas_bind and the server auto-detects it on startup.
What's in 1.0
- Scene graph → HTML/CSS → Puppeteer screenshots — agents author via MCP tools, you review real browser renders.
- Workspaces / projects and a Figma-style standalone viewer (read-only gallery across global + every bound repo).
- Design systems with workspace → project → canvas token inheritance.
- Responsive breakpoints (
stack/wrap/ fluid widths) with true reflow. - Evaluation — heuristic design scoring + optional LLM-as-judge, with auto-fix ops.
- Repo-bound storage — deterministic JSON, asset externalization (
.framesmith/assets/), external-change safety, viewer write-back.
Install
# Claude Code
claude mcp add framesmith -- npx framesmithWorks with any MCP client (Cursor, Windsurf, VS Code, Codex). See the README for per-client config.
MIT licensed.
v0.9.0 — Workspace-level design systems
Tokens declared once, inherited everywhere.
The Coide use case finally clicks: set the design system once on the workspace, every canvas under it resolves $primary / $bg / $lg automatically.
Highlights
Workspace.designSystem+ symmetricProject.designSystem— declare tokens once at the workspace level; projects can override.- Three-layer resolution at render:
canvas.variables(override) →project.designSystem→workspace.designSystem→ built-in defaults. Per-category merge — setting onlycolorsdoesn't resetspacing/radius/typography. - Six new MCP tools:
workspace_set_design_system,workspace_get_design_system,workspace_apply_preset+ symmetricproject_*trio. Presets (dark,light,material,minimal) installable at workspace OR project level. - Shared
getCanvasTokens(canvas)helper insrc/workspaces.ts— every render path (MCP tools, viewer, evaluate, canvas_diff) routes through it. The docstring warns against the anti-pattern that bit us in #40.
Authoring story
// Once per workspace — brand colors set globally
workspace_set_design_system({
workspaceId,
variables: {
colors: { primary: "#0066ff", bg: "#0a0a0a" },
spacing: { sm: 8, md: 16, lg: 24 }
}
});
// Every canvas under that workspace
batch_design({ canvasId, operations: 'I(parent, { fill: "$primary" })' });
// → resolves to #0066ff via workspace inheritance, no canvas-level redefinitionBonus
- Fix #40 — viewer / canvas_diff / evaluate were missed in the Phase 9 PR, leaving them with the old
resolveVariables(canvas.root, canvas.variables)bypass. Caught while dogfooding the release page. - Dogfood #41 —
scripts/build-phase9-showcase.tscomposes a single-canvas hero that visually documents canvas-mcp's design system AND proves three-layer inheritance works end-to-end (canvas itself hasvariables: {}— every value resolves from workspace tokens). Plus reorganized canvas-mcp's own dogfood artifacts intoDesign system / UI / Releasesprojects following Figma + atomic design + Spotify Encore conventions.
Backward compatibility
All Phase 9 additions are opt-in:
- Existing canvases without workspace/project
designSystemrender identically — the merge falls through tocanvas.variablesalone. setVariables/getVariables/ canvas-levelapply_presetunchanged.- Workspace/Project JSON gain an optional
designSystemfield; older persisted entries without it load cleanly.
No migration needed.
What's next
Only Phase 10 (Ecosystem — image generation, HTTP transport, VS Code extension, Figma import, marketplace, plugins) remains for the v1.0 push.
v0.8.0 — Renderer expressiveness
The renderer learned how to fade in, blur what's behind it, load a real typeface, draw a custom mark, and know which ancestor to anchor against.
Five primitives that expand what a canvas-mcp design can express. Every item came from a concrete Phase 7 slice-5 design moment the renderer couldn't render.
Highlights
- Auto
position: relative— frames automatically receiveposition: relativewhen a descendant usesposition: absolutewithout a positioned ancestor. Fixes the slice-5a "absolute child escapes to body coordinates" bug. (#31) - Custom fonts —
set_fonts/get_fontsMCP tools. Renderer emits@font-face+<link rel="preconnect">per origin +font-display: swap. (#32) backdropFilter— structured object withblur/saturate/brightness/contrast. Bothbackdrop-filterand-webkit-backdrop-filteremitted for Safari. LegacybackdropBlurstill works. (#33)pathnode type — custom SVG marks via rawd+viewBox. Fill/stroke apply to the path element (not the wrapper). Tight character whitelist ond. (#34)- Animations — structured
animationfield referencing built-in keyframes (fadeIn,slideUp,slideDown,scaleIn).@keyframesauto-emitted only when referenced. Structuredtransitionready for future hover/JS state changes. (#35)
Bonus
- Inline style escape fix —
"and&in CSS values now HTML-escape correctly. Found while dogfooding the release page withfontFamily: '"Inter", system-ui, sans-serif'(the inner"was prematurely closing the outerstyle="..."attribute). (#36) - Dogfood release page — single-canvas hero composed via canvas-mcp itself, exercising every Phase 8 primitive. Reproduce with
npx tsx scripts/build-phase8-release.ts, then visit/canvas/phase8-releasein the viewer to see animations play. (#37)
Backward compatibility
All Phase 8 additions are opt-in:
- Existing canvases without
fonts/animation/transition/backdropFilter/pathnodes render identically. - The legacy
backdropBlur: numberfield keeps working unchanged. - Auto
position: relativeonly applies via external stylesheet rule, so inlinepositiondeclarations always win. - The renderer escape fix is invisible to canvases that didn't trip the bug.
No migration needed.
What's next
Phase 9 — Workspace-level design systems. Promote per-canvas variables to workspace-inherited tokens with explicit per-canvas overrides. "Every Coide canvas should follow Coide's design system without redefining colors per canvas."
v0.7.0 — Workspace UI overhaul
canvas-mcp grows up from a flat dashboard into a real workspace. Workspaces → Projects → Canvases hierarchy on the MCP side, a Figma-style viewer with sidebar navigation and archive surface, and a visual refresh that drops the AI-default purple for a flat amber identity.
Highlights
- Hierarchy —
workspace_create/project_create/canvas_moveand friends. 11 new MCP tools let the AI organise canvases without the user touching the filesystem. - Sidebar viewer — workspaces and projects in a collapsible left sidebar, project-scoped main pane with breadcrumb, archive surface for soft-deleted canvases with restore + permadelete actions.
- Visual refresh — flat amber accent on warm-dark surfaces (no gradients, no purple), Linear-style restraint executed with a distinct identity. Cards get glass-rim shadows, empty thumbnails get the "layered canvas" treatment, detail toolbar groups buttons into clusters with hairline dividers.
- Mobile — sidebar collapses to an off-canvas drawer below 768px; detail toolbar stacks clusters into full-width rows with proper touch targets.
- Migration — existing canvases auto-gain a
projectIdon first load and land in the defaultPersonal / Untitledbucket. No manual intervention.
What's in this release (10 PRs)
- #21 Roadmap for Phase 7 added
- #22 Slice 1 data model + migration
- #23 Slice 2 workspace/project CRUD + canvas lifecycle MCP tools
- #24 Slice 3 empty thumbnail placeholder
- #25 Slice 4a sidebar + project-scoped main pane
- #26 Slice 4b archive surface + lifecycle UI
- #27 Slice 5a dogfood mock for the visual refresh
- #28 Slice 5b implementation (flat amber palette, mobile drawer, toolbar clusters)
- #29 Phase 7 closeout + Phase 8/9 roadmap added
- #30 Version bump
Backward compatibility
Existing canvas files gain "projectId": "default-project" on first load — one-shot rewrite, idempotent on subsequent runs. The MCP server adds 11 tools but doesn't change any existing tool surface. canvas_create and canvas_list are backward-compatible (new parameters are optional with sensible defaults).
What's next
Phase 8 (Renderer expressiveness) — backdrop-filter, custom font loading, SVG paths, animations. Every item came from a concrete slice 5 design moment the renderer couldn't express.
v0.6.0 — Evaluation & AI Loops
Phase 6 closes the generator-evaluator loop. canvas_evaluate now ships alongside a benchmark suite that catches scoring drift, a canvas_autofix tool that returns mechanical fixes as ready-to-run batch_design ops, and an opt-in LLM-judge mode that brings a vision model's holistic critique alongside the deterministic heuristics.
Highlights
canvas_autofixreturns the subset ofcanvas_evaluateissues that have a mechanically derived fix — off-scale spacing snaps to scale, multi-child frames withoutlayoutgetvertical, recoverable WCAG contrast failures get#000or#FFFbased on background luminance. Each fix is a ready-to-pastebatch_designUpdate op. Closes the loop without judgement calls.- LLM-judge mode —
canvas_evaluate({ mode: "llm" })runs the fast heuristics and adds anllmCritiquefield (score / summary / strengths / weaknesses / suggestions). Pluggable provider table: Anthropic Claude and OpenAI GPT shipped, third provider is one entry insrc/llm-judge.ts. Provider picked fromCANVAS_LLM_PROVIDERenv var or whichever API key is set. - Benchmark suite —
npm run benchrunscanvas_evaluateover a fixed corpus (hero,minimal,bad-contrast) and diffs againstbenchmark/baselines.json. Detects drift inoverallScore, per-category scores, issue counts, and issue messages. Re-baseline withnpx tsx benchmark/run.ts --update.
What's in this release (4 PRs)
- #17 Benchmark suite + drift-detecting runner
- #18
canvas_autofixwith mechanical fixes for spacing, layout, contrast - #19 LLM-judge mode (pluggable Anthropic / OpenAI)
- #20 Version bump
Backward compatibility
EvaluationResult.mode extends to 'fast' | 'detailed' | 'llm'; all new fields are optional. Heuristic-only callers see no breaking change. The benchmark runner uses fast mode, so adding llm does not affect existing baselines.
v0.5.0 — Responsive Layout
canvas-mcp is an open-source MCP server that gives any AI assistant a visual design canvas. This release makes canvases actually adapt across breakpoints instead of just rescaling.
Highlights
responsivehint on containers (stack/wrap/fixed) — author desktop-first, the renderer derives the mobile layout from the same scene graph.- Fluid widths —
width,minWidth,maxWidthaccept percentages,fit-content, and other CSS lengths so designs flex within bounds. - True reflow everywhere —
screenshot_responsivenow re-renders per breakpoint, and the viewer has a new Compare mode showing mobile / tablet / desktop side-by-side, each at its real viewport. - Authoring guidelines as an MCP resource (
canvas-mcp://guidelines): width strategies, common patterns, anti-patterns. - Renderer polish — system sans-serif default, root document fills + centers the viewport on wide screens,
batch_designparser handles embedded'Segoe UI'-style strings.
What's in this release (9 PRs)
- #6
responsivehint + renderer mapping - #7 Fluid widths (
minWidth/maxWidth) - #8 README hero composed via canvas-mcp itself
- #9 Default sans-serif at the renderer level
- #10 Root document fills + centers viewport
- #11 Quote-aware
batch_designparser - #12
canvas-mcp://guidelinesMCP resource - #13
screenshot_responsivetrue reflow - #14 Viewer Compare view
- #15 Version bump
Still open
- Phase 5 #8 (stretch) — per-breakpoint override map as opt-in escape hatch. Deferred by the original design memo.
- 768px breakpoint boundary fix (next PR after this tag).

