Zaai Dev MCP
Model Context Protocol server for the Zaai Dev platform. Exposes your captured design references to MCP-compatible AI tools — Claude Code, Claude Desktop, Cursor, Continue, Cline, anything else that speaks MCP.
After a one-time token paste, prompts like "list my last 5 captures tagged hero and show me their palettes" call the workspace directly and pull back real data.
Install
You need:
Claude Desktop
Add to claude_desktop_config.json — merge into the existing mcpServers block, don't replace the whole file.
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json
- Windows:
%APPDATA%\Claude\claude_desktop_config.json
- Linux:
~/.config/Claude/claude_desktop_config.json
{
"mcpServers": {
"zaai-dev": {
"command": "npx",
"args": ["-y", "@zaai-dev/mcp"],
"env": {
"ZAAI_API_TOKEN": "zaai_mcp_YOUR_SECRET_HERE"
}
}
}
}
Restart Claude Desktop. The 23 tools below appear in the slash-command picker.
Cursor
Add to ~/.cursor/mcp.json — same JSON shape as Claude Desktop.
{
"mcpServers": {
"zaai-dev": {
"command": "npx",
"args": ["-y", "@zaai-dev/mcp"],
"env": {
"ZAAI_API_TOKEN": "zaai_mcp_YOUR_SECRET_HERE"
}
}
}
}
Restart Cursor.
Claude Code (CLI)
One-liner — updates ~/.claude/mcp_servers.json automatically:
claude mcp add zaai-dev -e ZAAI_API_TOKEN=zaai_mcp_YOUR_SECRET_HERE -- npx -y @zaai-dev/mcp
Streamable HTTP (v0.3.0+, hosted-agent use cases)
If you want to run Zaai Dev MCP as a network service — e.g. behind a reverse proxy on Fly / Cloudflare / Render so hosted agents (Claude.ai web, OpenAI Assistants, custom frameworks) can reach it — use the zaai-dev-mcp-http binary instead of the stdio one:
ZAAI_API_TOKEN=zaai_mcp_... \
ZAAI_HTTP_PORT=3001 \
npx -y --package=@zaai-dev/mcp zaai-dev-mcp-http
Single-tenant in v1.5 — one process serves one workspace token. Run one process per token if you need multi-tenant, or wait for v2 which adds per-request token binding. Most "I want HTTP" use cases are single-tenant anyway.
Verify it's working
Three checks, cheapest first — climb until one fails and that's your problem:
health — no token, no network, no credits. Confirms the server process launched and speaks MCP. It's the first thing to click in the MCP Inspector; from an agent, ask "call the zaai-dev health tool". Returns { ok, version, node, uptimeSeconds }.
whoami — needs your token, still free. The first call that reaches the workspace: it returns your userId, orgId, project scope, and credit balance. If this works, your token is valid and you're fully connected. Ask "call whoami".
list_captures — needs token and real data (costs 1 credit). Returns your newest captures; if ids come back, the whole pipeline works end to end.
Reading the result:
health works but whoami returns Unauthorized → the token is wrong/revoked, or you pasted an extension token (zaai_ext_*) instead of an MCP one (zaai_mcp_*). Mint a fresh mcp token at /dev/settings/tokens and restart your client.
health itself doesn't run → the server never booted. Almost always a missing/blank ZAAI_API_TOKEN in your client config (the process fails fast on startup). Check the env block, then restart.
No client handy? Smoke-test the stdio binary straight from a terminal — initialize and call health over JSON-RPC (any non-empty zaai_mcp_* value gets you past the boot check, since health never hits the network):
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"smoke","version":"0"}}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized"}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"health","arguments":{}}}' \
| ZAAI_API_TOKEN=zaai_mcp_smoke npx -y @zaai-dev/mcp
See TROUBLESHOOTING.md for the full first-install checklist.
Tools
All tools except health need a valid token. All tools except health and whoami charge credits per successful call (your workspace plan determines the monthly grant — see pricing).
Captures (org-wide)
health | Server status + version + uptime. No auth. | 0 |
whoami | Your userId, orgId, project scope, credit balance. | 0 |
list_captures | Paginated list of your captures (newest first). Args: q, cursor, limit. | 1 |
search_captures | Same as list but with q required. Tuned description for targeted retrieval. | 1 |
get_capture | Full payload + signed screenshot URLs for one capture id. | 1 |
get_palette | Just the palette slice (page) or eyedropper picks (element/composite). | 1 |
get_html | Just the HTML. Page → full HTML; element → outerHTML; composite → concat with markers. | 1 |
get_animation | Just the animation data — CSS transitions, keyframes, library hints. | 1 |
get_media | Just the media inventory — videos, images, backgrounds, carousels. | 1 |
get_structure | Just the Layer-Explorer teardown — the structure map (nodes w/ depth, rects, selectors, components, flags). Page/element → one map; composite → per-element. | 1 |
Brand brief + references (project-scoped, v0.2.0+)
These tools each take a project_id arg (find via the workspace at zaaidev.com/dev/projects/<id> — the UUID is in the URL). The five brief-read tools also accept an optional brief_id to target a specific brief on projects that have more than one; omit it for the project's default brand-identity brief.
list_briefs | Every brief on a project — id, type, name, status, current-version metadata. Call first, then pass brief_id. | 1 |
get_brand_brief | Full published brief: positioning, values, voice, audience, design intent, decisions. Optional brief_id. | 1 |
get_voice | Voice slice only — one-liner, tone descriptors, do/don't say, example phrases. Optional brief_id. | 1 |
get_audience | Primary + secondary segments, needs, channels. Optional brief_id. | 1 |
get_design_intent | Descriptors + anti-descriptors + inspiration summary. Optional brief_id. | 1 |
get_brand_tokens | Colors, fonts, radius, shadow scales. Optional brief_id. | 1 |
get_decisions | Paginated decisions log with attribution + brief_field links. | 1 |
log_decision | Record a brand/design decision (what, why, optional brief_field). Write tool. | 1 |
get_references | Paginated project-scoped reference list. | 1 |
search_references | Keyword search within a project's references. | 1 |
add_reference | Create a URL-only reference capture from a link. Write tool. | 5 |
Docs / block-docs (project-scoped, v0.3.0+)
list_docs | Every doc on a project — id, type, name, status, current-version metadata. Friendly alias of list_briefs. | 1 |
get_doc | A doc as an agent-ready block list — text + capture references with role/treatment, the captured code (element outerHTML + computed CSS + build tokens, or page HTML) to build from real values, and the sign-off (approval) signal. Omit doc_id for the brand-identity doc. | 1 |
get_project_bundle | The whole project in one call — project meta, all docs (as above), and capture summaries. Can be large. | 1 |
Plus the zaai-capture://{id} resource template — attach individual captures to a conversation via the resource picker.
Errors
Unauthorized | Token invalid, revoked, or wrong kind | Mint a fresh mcp token, update your config, restart |
InsufficientCredits | Out of credits for the month | Top up or wait for the monthly grant |
CaptureNotFound | id doesn't exist OR is in a project the token can't see | list_captures to find valid ids |
InvalidCaptureId / InvalidProjectId | id isn't a UUID | Pass a UUID from list_captures / the workspace URL |
ProjectNotFound | project_id isn't in your org | Check the id, or that the token's project scope allows this project |
ProjectArchived | Project exists but is archived | Unarchive in the workspace or use a different project |
OutOfScope | Token is scoped to specific projects + this isn't one of them | Mint a token without project scope, or add this project to the existing token |
wrong_brief_type | A brief tool was called against a brief of the wrong type | Use list_briefs to find a brief of the expected type, pass its brief_id |
InvalidDocId | get_doc was passed a malformed doc id | Use list_docs for valid ids, or omit doc_id for the default doc |
RateLimited | Exceeded ~60 calls/min for this token | The server already retried with backoff — wait a moment before retrying |
UnknownCaptureField | Hit a focused-getter route with an unknown field | Use one of: palette, html, animation, media, structure |
Errors return as isError: true in the tool result so the LLM can read and act on them.
Transient failures (network errors, 502/503/504, 429 rate-limits) retry automatically with exponential backoff (250ms → 500ms → 1000ms, 3 attempts). Retries are transparent — you only see the final outcome — and don't double-charge because the workspace only bills on requests that actually executed.
Troubleshooting
See TROUBLESHOOTING.md for a checklist of common first-install issues and their fixes.
Privacy + scoping
The server holds only your MCP token — it never sees your password, your Supabase service-role key, or other users' data. The workspace's verifyToken derives userId + orgId from your token on every request; queries are scoped to that user + the token's project allowlist (which you set at mint time). A revoked token causes the next tool call to fail with Unauthorized.
The server itself runs entirely on your machine — npx -y @zaai-dev/mcp downloads the package once, then your AI tool launches it as a subprocess. No telemetry, no analytics SDK.
Building locally
git clone https://github.com/POLONIBOI/ZAAI_dev_mcp.git
cd ZAAI_dev_mcp
pnpm install
pnpm build
pnpm inspector
You'll need ZAAI_API_TOKEN set as an env var (or pasted into the Inspector's Environment Variables panel before clicking Connect).
License
MIT.