<div align="center"> <img src="assets/banner.svg" alt="mockit-mcp" width="100%"/>
<h1>mockit-mcp</h1>
<p><strong>Turn text prompts into premium iOS mobile UI mockups.</strong></p> <p>An MCP server that pairs Claude (Opus 4.7 by default) with a Playwright renderer to generate <em>screenshot-grade</em> mobile app designs from natural language.</p>
<p> <a href="https://github.com/karyaboyraz/mockit-mcp/releases/latest"><img src="https://img.shields.io/github/v/release/karyaboyraz/mockit-mcp?style=for-the-badge&color=BF5AF2&label=release" alt="Latest release"/></a> <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-34C759?style=for-the-badge" alt="MIT License"/></a> <a href="https://github.com/karyaboyraz/mockit-mcp/stargazers"><img src="https://img.shields.io/github/stars/karyaboyraz/mockit-mcp?style=for-the-badge&color=FFD60A&logo=github&logoColor=white" alt="GitHub stars"/></a> <a href="https://github.com/karyaboyraz/mockit-mcp/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/karyaboyraz/mockit-mcp/ci.yml?style=for-the-badge&label=ci" alt="CI status"/></a> </p> <p> <img src="https://img.shields.io/badge/Node.js-%E2%89%A520-339933?style=flat-square&logo=node.js&logoColor=white" alt="Node.js 20+"/> <img src="https://img.shields.io/badge/TypeScript-strict-3178C6?style=flat-square&logo=typescript&logoColor=white" alt="TypeScript strict"/> <img src="https://img.shields.io/badge/MCP-1.0-BF5AF2?style=flat-square" alt="MCP 1.0"/> <img src="https://img.shields.io/badge/Claude-Opus%204.7-D97757?style=flat-square" alt="Claude Opus 4.7"/> <img src="https://img.shields.io/badge/Playwright-headless-2EAD33?style=flat-square&logo=playwright&logoColor=white" alt="Playwright"/> </p> </div>
---
What it does
Ask Claude Code (or any MCP client):
Design the home dashboard for a fitness tracker. Three concentric activity rings, weekly bar chart, recent workouts list, premium dark mode with neon accents.
mockit-mcp returns a real PNG mockup (sized 390Γ844 at 2x device scale, an iPhone-class viewport) and the underlying HTML/Tailwind source β so you can iterate visually and port to SwiftUI when you're ready to build.
It's not a static template engine and it's not generic AI slop. The system prompt is hand-tuned for premium iOS aesthetics: real content, SVG icons (no emoji), tasteful gradients in place of stock photos, iOS HIG type scale, and tonal layering instead of heavy shadows.
<div align="center"> <table> <tr> <td align="center"><img src="examples/screens/fitness.png" width="280" alt="Fitness tracker dashboard"/><br/><sub><b>Fitness dashboard</b></sub></td> <td align="center"><img src="examples/screens/volumetrik.png" width="280" alt="Volume calculator app screen (Turkish)"/><br/><sub><b>Volume calculator</b> (Turkish)</sub></td> </tr> </table> <p><sub>Generated from a single prompt each. See <a href="examples/">examples/</a>.</sub></p> </div>
Highlights
- Two backends, same tools. Use the local
claudeCLI (subscription, $0 extra) or the Anthropic API (key + per-call pricing). Switch with one env var. - Real PNG output. Headless Chromium via Playwright. Default viewport is 390Γ844 @2x (iPhone-class); any custom size is one env var away.
- Iterative refinement.
iterate_screentakes a screen ID + feedback ("make the hero card smaller") and produces a new version, tracking parent/child. - Disk-backed library. Every generation saves HTML + PNG + JSON metadata. Browse, filter, re-export.
- MCP standard. Works with Claude Code, Claude Desktop, Cursor, Windsurf, or any MCP client.
- Stdio + HTTP transports. Run locally for dev, or as a network service for shared / containerized use.
Tools
| Tool | Description | |------|-------------| | generate_screen | Text brief β PNG + HTML. Optional design_system and project fields. | | iterate_screen | Take a previous screen_id + feedback string, produce a new version. | | list_screens | List screens, optionally filtered by project. | | get_screen | Fetch metadata (or full HTML) for a specific screen. |
Install
Prerequisites
- Node.js 20+
- Either the
claudeCLI logged in (clibackend, default) or an Anthropic API key (apibackend) - Playwright's Chromium download (~170 MB, one-time)
Quick start (CLI backend, recommended for local dev)
git clone https://github.com/karyaboyraz/mockit-mcp.git
cd mockit-mcp
npm install
npx playwright install chromium
npm run build
Add to Claude Code:
claude mcp add mockit -- node "$(pwd)/dist/server.js"
Done. No API key needed β it uses your existing claude CLI session.
API backend (no claude CLI on host)
echo "CLAUDE_BACKEND=api" > .env
echo "ANTHROPIC_API_KEY=sk-ant-..." >> .env
npm run build
claude mcp add mockit -- node "$(pwd)/dist/server.js"
Docker (HTTP transport, for shared deployment)
cat > .env <<'ENV'
CLAUDE_BACKEND=api
ANTHROPIC_API_KEY=sk-ant-...
# Required if you change the port binding from 127.0.0.1 to 0.0.0.0:
MCP_HTTP_TOKEN=$(openssl rand -hex 32)
ENV
docker compose up -d --build
By default docker-compose.yml binds the HTTP port to 127.0.0.1 only and the server requires MCP_HTTP_TOKEN for any non-loopback request. Don't expose this server to a public network without setting a strong MCP_HTTP_TOKEN β every generation hits your Anthropic API key.
Then point any client at the loopback URL:
claude mcp add --transport http mockit http://127.0.0.1:7821/mcp \
-H "Authorization: Bearer <MCP_HTTP_TOKEN>"
For remote access, change docker-compose.yml's port binding to 0.0.0.0:7821:7821 and ensure MCP_HTTP_TOKEN is set β the server refuses to start otherwise.
Usage
In any MCP client, just ask:
Design a fitness tracker dashboard. Show today's ring progress, a weekly chart, and a list of recent workouts. Dark mode, neon green accent.
The PNG appears inline. The HTML is saved to designs/{project}/{name}-{id}.html.
For follow-ups:
iterate_screen on that fitness dashboard β replace the chart with heart-rate over time, and add a "share workout" button below.
See examples/ for prompt patterns and full outputs.
Configuration
All optional. See .env.example for the full list.
| Env | Default | Notes | |-----|---------|-------| | CLAUDE_BACKEND | cli | cli uses the claude CLI; api uses Anthropic SDK directly | | ANTHROPIC_API_KEY | β | Required only for api backend | | ANTHROPIC_MODEL | claude-opus-4-7 | API backend only. If your account doesn't have Opus access, set to claude-sonnet-4-6 or claude-haiku-4-5 | | CLAUDE_CLI_PATH | claude | Path to the claude binary | | CLAUDE_CLI_TIMEOUT_MS | 180000 | Subprocess timeout | | MCP_TRANSPORT | stdio | stdio or http | | HTTP_PORT | 7821 | HTTP transport port | | HTTP_HOST | 127.0.0.1 | Bind interface; non-loopback requires MCP_HTTP_TOKEN | | MCP_HTTP_TOKEN | β | Bearer token for HTTP auth. Required if HTTP_HOST is non-loopback | | DESIGNS_DIR | ./designs | Where outputs are persisted | | VIEWPORT_WIDTH | 390 | Render width in CSS pixels | | VIEWPORT_HEIGHT | 844 | Render height in CSS pixels | | DEVICE_SCALE | 2 | Retina factor (final PNG is WIDTH Γ DEVICE_SCALE wide) | | PLAYWRIGHT_NO_SANDBOX | auto | auto = sandbox enabled outside containers; true to force-disable, false to force-enable. Disabling reduces isolation against malicious model HTML β only do so inside a container. |
Cost
Per generation: ~3K input tokens (system prompt) + ~6β12K output tokens depending on screen complexity. Output dominates the cost on Opus.
| Backend | First call | Cached follow-up | |---------|-----------|------------------| | cli | counts against your Claude Code subscription quota | same β cache only discounts the system prompt | | api | ~$0.50β0.95 (Opus 4.7) | ~$0.45β0.90 (cache discounts the system-prompt input only; output cost is unchanged) |
System-prompt caching is on by default (5-minute TTL). It saves a few cents per call but is not an order-of-magnitude discount β output tokens still bill at full rate. For real cost reduction, switch to a smaller model (claude-sonnet-4-6 or claude-haiku-4-5).
Architecture
βββββββββββββββββββ
β MCP Client β (Claude Code, Cursor, Windsurf, β¦)
ββββββββββ¬βββββββββ
β tool call: generate_screen({ prompt, ... })
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β mockit-mcp β
β β
β ββββββββββββββββ ββββββββββββββββββββββββββ β
β β Backend β β Renderer β β
β β β β β β
β β βΊ cli ββββββΌβββΊ β Playwright (headless β β
β β βΊ api ββββββ β Chromium @ iPhone β β
β β β HTML+Tailwind β viewport) β β
β ββββββββββββββββ β β PNG screenshot β β
β ββββββββββββββββββββββββββ β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββ β
β β Storage (disk): HTML + PNG + JSON metadata β β
β ββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Storage layout
designs/
βββ {project-slug}/
βββ {name-slug}-{id8}.html # id8 = first 8 chars of the screen UUID
βββ {name-slug}-{id8}.png
βββ {name-slug}-{id8}.json # full UUID, prompt, parent ID, tokens, model, cost
Documentation
Reference and guides live in docs/:
| Topic | Page | |-------|------| | Install, first generation, verify | Getting Started | | Every env var, defaults, what they do | Configuration | | The four MCP tools β schemas, examples | Tools Reference | | Pipeline end-to-end | Architecture | | Local, Docker, networked deployments | Deployment | | Sandbox, network allowlist, HTTP auth | Security | | How the design voice is encoded | System Prompt | | Common errors and how to fix them | Troubleshooting |
Tuning the design voice
The hand-tuned system prompt lives in src/system-prompt.ts. It's where the iOS HIG enforcement, the no-stock-photo rule, the SF Pro fallback chain, and the editorial typography preferences are encoded. Want Material You instead, or a desktop dashboard voice? Edit it.
Development
npm run dev # tsx watch mode, stdio transport
npm run http # tsx watch mode, http transport on :7821
npm run build # compile to dist/
Roadmap
- [ ] Watch / iPad / Android viewport presets
- [ ] Multi-screen flow generation (onboarding sequences)
- [ ] HTML β SwiftUI / Jetpack Compose port tool
- [ ] Design system import (Tailwind config, design tokens)
- [ ] Image references (use
--imagefor visual inspiration) - [ ] Variant generation (3-5 alternatives per prompt)
Contributing
Issues and PRs welcome β see CONTRIBUTING.md.
License
Acknowledgements
Built on top of:
- Anthropic Claude β the model that does the heavy lifting
- Model Context Protocol β the integration standard
- Playwright β the renderer
- Tailwind CSS β via CDN, in every generated screen
Trademarks
iPhone, iPad, Apple Watch, and iOS are trademarks of Apple Inc. Claude is a trademark of Anthropic, PBC. mockit-mcp is an independent open-source project and is not affiliated with, endorsed by, or sponsored by Apple Inc. or Anthropic, PBC. All other product names, logos, and brands are property of their respective owners.











