Minimal Designer

Minimal Designer

MCP server for AI-first UI design that enables Codex to create, preview, and commit UI changes to a self-hosted design tool.

Category
Visit Server

README

Minimal Designer

A self-hosted, AI-first UI designer for product teams. Product managers describe screens to Codex; Codex creates a validated preview through MCP, inspects the rendered result, and commits it to the same document that people edit in the browser.

The project is intentionally smaller than Figma: it focuses on structured web, phone, and tablet UI, design tokens, editable handoff, simple prototype links, and immutable history. It does not require an OpenAI API key and has no hosted designer dependency. Your existing Codex access is separate.

Easiest first run

Run the launcher from the project directory:

./designer

It detects macOS, Linux, or WSL; checks ports and requirements; and guides you through local Docker, native development, or server setup. Docker local mode is recommended because it includes Node, Chromium, and all native dependencies. On macOS, the launcher can also offer to start Docker Desktop when it is installed but its engine is stopped.

For a non-interactive diagnosis and Docker start:

./designer doctor auto
./designer start docker

Open http://127.0.0.1:4310. The launcher keeps generated configuration, process state, logs, backups, and server secrets under the ignored .designer/ directory. Project data is persisted in the designer-data Docker volume.

Use ./designer --dry-run start docker to inspect a startup plan without installing packages, writing runtime files, or starting a process/container.

Local Docker

Requirements: Docker Desktop, or Docker Engine with Compose v2. Make sure the Docker engine is running, then use:

./designer setup docker
./designer start docker

The setup command only checks Docker and Compose. start docker builds the single application image, binds it to loopback, waits for readiness, and opens the editor. Useful variants are:

./designer start docker --port 4410 --no-open
./designer start docker --no-build

Keep the default loopback binding while AUTH_MODE=none. To run Compose directly instead of using the launcher:

docker compose up --build

Native development and local production

Requirements: Node.js 24+, pnpm 11+, and a Chromium browser for server-side PNG rendering. The launcher can prepare dependencies, build bundled fonts, verify SQLite, and optionally install Playwright Chromium:

./designer doctor local
./designer setup local
./designer dev

Development mode runs until Ctrl+C:

After the first setup, use ./designer dev --skip-setup for a faster restart. To run the built application in the background instead, use:

./designer start local

The renderer automatically tries an installed Google Chrome/Chromium. Docker already contains the matching Playwright browser.

Server deployment

The launcher supports two safe server configurations. Both keep the application port bound to 127.0.0.1 on the server.

For a private server reached only through SSH:

# On the server
./designer server init --ssh-only
./designer start server

# On your computer
ssh -L 4310:127.0.0.1:4310 user@your-server

Keep that SSH session open, then use http://127.0.0.1:4310 in the browser and in the local Codex MCP configuration.

For an internal company URL behind an existing HTTPS/SSO reverse proxy:

./designer server init --public-url https://designer.company.example
./designer start server

This generates a protected MCP bearer token and configures trusted-header UI authentication. The proxy must authenticate users, remove any client-supplied identity header, set the verified identity header itself, forward bearer authorization to /mcp, and disable buffering for SSE. See docs/deployment.md before exposing the service.

Operations

The same commands work for native, Docker, and server modes where applicable:

./designer status
./designer logs
./designer logs --follow
./designer open
./designer restart
./designer stop
./designer backup /safe/path/designer-backup

stop preserves persistent design data. A backup includes SQLite/WAL state and assets; the launcher briefly stops a Docker service while copying a consistent snapshot.

Connect Codex through MCP

Print the correct local configuration with:

./designer codex-config local

Copy its output into the trusted project's .codex/config.toml or the global ~/.codex/config.toml, then restart Codex. The generated local configuration is equivalent to:

[mcp_servers.minimal_ui]
url = "http://127.0.0.1:4310/mcp"
required = true
default_tools_approval_mode = "writes"
tool_timeout_sec = 60

SSH-only deployments use this same local configuration while the tunnel is open. For a trusted-proxy deployment, run these commands on the server:

./designer codex-config server
./designer token

Copy the first command's TOML to the Codex computer and set MINIMAL_UI_MCP_TOKEN there to the second command's value. Treat that output as a secret: do not paste it into TOML, logs, shell scripts, or source control. The server configuration uses bearer_token_env_var = "MINIMAL_UI_MCP_TOKEN".

The intended Codex workflow is:

  1. Read the active context or select a design explicitly.
  2. Build a complete change with design_preview_changes. Existing entities use permanent IDs; new entities may use transaction-local IDs such as tmp:header.
  3. Inspect the returned PNG and lint diagnostics.
  4. Commit the exact preview with design_commit_preview.
  5. Open the returned deep link for human review. On VERSION_CONFLICT, read the new head and create a new preview.

The application itself does not need an OpenAI API key.

Development verification

Run the launcher checks and workspace verification with:

pnpm test:launcher
pnpm typecheck
pnpm test:run
pnpm build

Configuration

Variable Default Purpose
HOST 127.0.0.1 Bind address. Docker overrides it to 0.0.0.0.
PORT 4310 HTTP port.
BIND_ADDRESS 127.0.0.1 Docker host interface. Do not use 0.0.0.0 with AUTH_MODE=none.
DATA_DIR ./data SQLite, assets, and render storage.
PUBLIC_BASE_URL local API URL Deep-link and render URL base.
AUTH_MODE none Use none on loopback or trusted-header behind the company proxy. token is intended for headless API access, not the browser UI.
DESIGNER_TOKEN empty Required bearer token in token and trusted-header modes; MCP always uses it in server mode.
TRUSTED_USER_HEADER x-designer-user Identity header set by a trusted proxy.
MAX_UPLOAD_BYTES 5242880 Maximum asset upload size.
DESIGNER_API_URL http://127.0.0.1:4310 API URL used by the Vite development editor.
DESIGNER_WEB_HOST 127.0.0.1 Vite development bind address.
DESIGNER_WEB_PORT 4311 Vite development port.

Manual backup and restore

Prefer ./designer backup [DESTINATION]. If you started the application with plain docker compose up instead of the launcher, SQLite uses WAL, so stop the application container before a manual filesystem copy:

docker compose stop designer
mkdir -p backups/designer-data
docker compose cp designer:/data/. backups/designer-data/
docker compose start designer

Restore into an empty replacement data volume while the container is stopped, copy the complete directory back to /data, then start the service. Verify /ready, open revision history, and fetch at least one uploaded asset before reopening writes. The database, WAL files, asset BLOBs, and immutable revisions must always be backed up and restored together.

V1 boundaries

The V1 document uses fixed-size frames with absolute, row, column, and simple grid layouts. It includes deterministic Latin and RTL text behavior. Realtime multiplayer, arbitrary vector paths, linked component variants, Figma import, animation, production-code generation, and plugins are intentionally deferred.

See docs/architecture.md for the internal model. For a secured company deployment, follow docs/deployment.md.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured